* [PATCH] prism54: wpa support for fullmac cards
@ 2006-10-03 12:57 chunkeey
2006-10-04 10:38 ` Jiri Benc
2006-10-17 21:32 ` John W. Linville
0 siblings, 2 replies; 39+ messages in thread
From: chunkeey @ 2006-10-03 12:57 UTC (permalink / raw)
To: netdev; +Cc: chunkeey
[-- Attachment #1: Type: text/plain, Size: 807 bytes --]
This patch (prism54-en-wpa3.patch) brings WPA/WPA2(RSN) with
TKIP-Cipher to everyone with a FULLMAC Prism GT/Indigo/Duette card.
I removed all the parts(e.g.: Hostapd Support) which are not relevant for
wpa_supplicant (client/managed mode).
now, you can connect to your WLAN with:
wpa_supplicant -Dwext -c{WPA_CONF} -i{WPA_ETH} -dd
This code is just for review & testers...
so only a pre-signed-off for now. ;)
Pre- Signed-off-by: Christian Lamparter <chunkeey@web.de>
---
diffstat:
isl_ioctl.c | 1560
+++++++++++++++++++++----------------------------------
isl_ioctl.h | 6
isl_oid.h | 99 ++-
islpci_dev.c | 1
islpci_hotplug.c | 11
islpci_mgt.h | 4
oid_mgt.c | 48 +
oid_mgt.h | 2
8 files changed, 724 insertions(+), 1007 deletions(-)
[-- Attachment #2: prism54-en-wpa3.patch --]
[-- Type: text/x-diff, Size: 68333 bytes --]
diff -Nurp a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
--- a/drivers/net/wireless/prism54/isl_ioctl.c 2006-09-28 21:13:25.000000000 +0200
+++ b/drivers/net/wireless/prism54/isl_ioctl.c 2006-10-03 14:27:01.000000000 +0200
@@ -4,6 +4,7 @@
* (C) 2003,2004 Aurelien Alleaume <slts@free.fr>
* (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
* (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
+ * (C) 2006 Christian Lamparter <chunkeey@web.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -35,10 +36,12 @@
#include <net/iw_handler.h> /* New driver API */
-#define KEY_SIZE_WEP104 13 /* 104/128-bit WEP keys */
-#define KEY_SIZE_WEP40 5 /* 40/64-bit WEP keys */
+#define KEY_SIZE_WEP40 5 /* short WEP keys */
/* KEY_SIZE_TKIP should match isl_oid.h, struct obj_key.key[] size */
-#define KEY_SIZE_TKIP 32 /* TKIP keys */
+#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
+#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
+
+static u8 wpa_oid[4] = { 0x00, 0x50, 0xf2, 1 };
static void prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid,
u8 *wpa_ie, size_t wpa_ie_len);
@@ -168,14 +171,16 @@ prism54_update_stats(islpci_private *pri
if (down_interruptible(&priv->stats_sem))
return;
-/* Noise floor.
- * I'm not sure if the unit is dBm.
- * Note : If we are not connected, this value seems to be irrelevant. */
+ /* Noise floor.
+ * I'm not sure if the unit is dBm.
+
+ * Note :
+ * If we are not connected, this value seems to be irrelevant. */
mgt_get_request(priv, DOT11_OID_NOISEFLOOR, 0, NULL, &r);
priv->local_iwstatistics.qual.noise = r.u;
-/* Get the rssi of the link. To do this we need to retrieve a bss. */
+ /* Get the rssi of the link. To do this we need to retrieve a bss. */
/* First get the MAC address of the AP we are associated with. */
mgt_get_request(priv, DOT11_OID_BSSID, 0, NULL, &r);
@@ -200,11 +205,11 @@ prism54_update_stats(islpci_private *pri
/* report that the stats are new */
priv->local_iwstatistics.qual.updated = 0x7;
-/* Rx : unable to decrypt the MPDU */
+ /* Rx : unable to decrypt the MPDU */
mgt_get_request(priv, DOT11_OID_PRIVRXFAILED, 0, NULL, &r);
priv->local_iwstatistics.discard.code = r.u;
-/* Tx : Max MAC retries num reached */
+ /* Tx : Max MAC retries num reached */
mgt_get_request(priv, DOT11_OID_MPDUTXFAILED, 0, NULL, &r);
priv->local_iwstatistics.discard.retries = r.u;
@@ -436,11 +441,11 @@ prism54_get_range(struct net_device *nde
/* Now the encoding capabilities */
range->num_encoding_sizes = 3;
/* 64(40) bits WEP */
- range->encoding_size[0] = 5;
+ range->encoding_size[0] = KEY_SIZE_WEP40;
/* 128(104) bits WEP */
- range->encoding_size[1] = 13;
+ range->encoding_size[1] = WEP_KEY_LEN;
/* 256 bits for WPA-PSK */
- range->encoding_size[2] = 32;
+ range->encoding_size[2] = SCM_KEY_LEN;
/* 4 keys are allowed */
range->max_encoding_tokens = 4;
@@ -876,15 +881,6 @@ prism54_set_rate(struct net_device *ndev
data[1] = 0;
}
-/*
- i = 0;
- printk("prism54 rate: ");
- while(data[i]) {
- printk("%u ", data[i]);
- i++;
- }
- printk("0\n");
-*/
profile = -1;
ret = mgt_set_request(priv, DOT11_OID_PROFILES, 0, &profile);
ret |= mgt_set_request(priv, DOT11_OID_EXTENDEDRATES, 0, data);
@@ -1053,18 +1049,58 @@ prism54_get_retry(struct net_device *nde
}
static int
+prism54_set_auth_alg(islpci_private *priv, u32 flag)
+{
+ int authen = DOT11_AUTH_NONE, invoke = 0, exunencrypt = 0;
+ int ret;
+
+ if (flag & IW_ENCODE_RESTRICTED) {
+ authen = DOT11_AUTH_SK;
+ invoke = 1;
+ exunencrypt = 1;
+ }
+
+ if (flag & IW_ENCODE_OPEN) {
+ authen = DOT11_AUTH_OS;
+ invoke = 1;
+ /*
+ This is very wrong here, but we've to ensure bug-to-bug compatibility.
+
+ If we set exunencrypt, the Firmware adds the "Privacy" flag to the
+ Capability Information, which is misreaded by many STA/AP as
+ "the device supports WEP, WPA and WPA2"
+ */
+ exunencrypt = 1;
+ }
+
+ ret =
+ mgt_set_request(priv, DOT11_OID_AUTHENABLE,
+ 0, &authen);
+ ret |=
+ mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED,
+ 0, &invoke);
+ ret |=
+ mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED,
+ 0,&exunencrypt);
+
+ return ret;
+}
+
+static int
prism54_set_encode(struct net_device *ndev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
- int rvalue = 0, force = 0;
- int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0;
+ int rvalue = 0, flags = dwrq->flags;
union oid_res_t r;
/* with the new API, it's impossible to get a NULL pointer.
* New version of iwconfig set the IW_ENCODE_NOKEY flag
* when no key is given, but older versions don't. */
+ if (islpci_get_state(priv) < PRV_STATE_INIT)
+ return -EINVAL;
+
if (dwrq->length > 0) {
/* we have a key to set */
int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
@@ -1076,23 +1112,23 @@ prism54_set_encode(struct net_device *nd
current_index = r.u;
/* Verify that the key is not marked as invalid */
if (!(dwrq->flags & IW_ENCODE_NOKEY)) {
- if (dwrq->length > KEY_SIZE_TKIP) {
+ if (dwrq->length > MAX_KEY_LEN) {
/* User-provided key data too big */
return -EINVAL;
}
- if (dwrq->length > KEY_SIZE_WEP104) {
+ if (dwrq->length > WEP_KEY_LEN) {
/* WPA-PSK TKIP */
key.type = DOT11_PRIV_TKIP;
- key.length = KEY_SIZE_TKIP;
+ key.length = MAX_KEY_LEN;
} else if (dwrq->length > KEY_SIZE_WEP40) {
/* WEP 104/128 */
- key.length = KEY_SIZE_WEP104;
+ key.length = WEP_KEY_LEN;
} else {
/* WEP 40/64 */
key.length = KEY_SIZE_WEP40;
}
memset(key.key, 0, sizeof (key.key));
- memcpy(key.key, extra, dwrq->length);
+ memcpy(key.key, extra, key.length);
if ((index < 0) || (index > 3))
/* no index provided use the current one */
@@ -1109,95 +1145,111 @@ prism54_set_encode(struct net_device *nd
* This is also how "iwconfig ethX key on" works
*/
if ((index == current_index) && (key.length > 0))
- force = 1;
+ flags |= IW_ENCODE_RESTRICTED;
} else {
- int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
+ int index = (flags & IW_ENCODE_INDEX) - 1;
if ((index >= 0) && (index <= 3)) {
/* we want to set the key index */
rvalue |=
mgt_set_request(priv, DOT11_OID_DEFKEYID, 0,
&index);
} else {
- if (!dwrq->flags & IW_ENCODE_MODE) {
+ if (!(flags & IW_ENCODE_MODE)) {
/* we cannot do anything. Complain. */
return -EINVAL;
}
}
}
- /* now read the flags */
- if (dwrq->flags & IW_ENCODE_DISABLED) {
- /* Encoding disabled,
- * authen = DOT11_AUTH_OS;
- * invoke = 0;
- * exunencrypt = 0; */
- }
- if (dwrq->flags & IW_ENCODE_OPEN)
- /* Encode but accept non-encoded packets. No auth */
- invoke = 1;
- if ((dwrq->flags & IW_ENCODE_RESTRICTED) || force) {
- /* Refuse non-encoded packets. Auth */
- authen = DOT11_AUTH_BOTH;
- invoke = 1;
- exunencrypt = 1;
- }
/* do the change if requested */
- if ((dwrq->flags & IW_ENCODE_MODE) || force) {
- rvalue |=
- mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
- rvalue |=
- mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &invoke);
- rvalue |=
- mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0,
- &exunencrypt);
- }
+ if (flags & IW_ENCODE_MODE)
+ rvalue = prism54_set_auth_alg(priv, flags);
+
return rvalue;
}
static int
+prism54_get_auth_algs(islpci_private *priv)
+{
+ u32 authen = 0, invoke = 0, exunencrypt = 0;
+ union oid_res_t r;
+ int ret = 0;
+
+ ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
+ authen = r.u;
+ ret |= mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
+ invoke = r.u;
+ ret |= mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
+ exunencrypt = r.u;
+
+ if (ret)
+ return ret;
+
+ if (invoke && exunencrypt &&
+ ((authen == DOT11_AUTH_SK) || (authen == DOT11_AUTH_BOTH)))
+ ret = IW_ENCODE_RESTRICTED | IW_ENCODE_ENABLED;
+ else if ((authen == DOT11_AUTH_OS)) {
+ if (invoke)
+ ret = IW_ENCODE_OPEN | IW_ENCODE_ENABLED;
+ else {
+ ret = IW_ENCODE_DISABLED;
+ }
+ }
+ else {
+ ret = IW_ENCODE_DISABLED;
+ }
+
+ return ret;
+}
+
+static int
prism54_get_encode(struct net_device *ndev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
struct obj_key *key;
u32 devindex, index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
- u32 authen = 0, invoke = 0, exunencrypt = 0;
- int rvalue;
+ int rvalue = 0, flags;
union oid_res_t r;
+ if (islpci_get_state(priv) < PRV_STATE_INIT) {
+ dwrq->flags = IW_ENCODE_DISABLED;
+ dwrq->length = 0;
+ return 0;
+ }
+
/* first get the flags */
- rvalue = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
- authen = r.u;
- rvalue |= mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
- invoke = r.u;
- rvalue |= mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
- exunencrypt = r.u;
+ if ((flags = prism54_get_auth_algs(priv)) < 0)
+ return rvalue;
- if (invoke && (authen == DOT11_AUTH_BOTH) && exunencrypt)
- dwrq->flags = IW_ENCODE_RESTRICTED;
- else if ((authen == DOT11_AUTH_OS) && !exunencrypt) {
- if (invoke)
- dwrq->flags = IW_ENCODE_OPEN;
- else
- dwrq->flags = IW_ENCODE_DISABLED;
- } else
- /* The card should not work in this state */
- dwrq->flags = 0;
+ memset(extra, 0x0, dwrq->length);
+ dwrq->flags = flags;
- /* get the current device key index */
- 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))
- /* no index provided, use the current one */
- index = devindex;
- rvalue |= mgt_get_request(priv, DOT11_OID_DEFKEYX, index, NULL, &r);
- key = r.ptr;
- dwrq->length = key->length;
- memcpy(extra, key->key, dwrq->length);
- kfree(key);
- /* return the used key index */
- dwrq->flags |= devindex + 1;
+ if (flags != IW_ENCODE_DISABLED) {
+ /* get the current device key index */
+ 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))
+ /* no index provided, use the current one */
+ index = devindex;
+
+ rvalue |= mgt_get_request(priv, DOT11_OID_DEFKEYX, index, NULL, &r);
+ key = r.ptr;
+
+ if (dwrq->length < key->length) {
+ kfree(key);
+ return -EINVAL;
+ }
+ dwrq->length = key->length;
+ memcpy(extra, key->key, dwrq->length);
+ kfree(key);
+ /* return the used key index */
+ dwrq->flags |= devindex + 1;
+ } else
+ rvalue = 0;
+
return rvalue;
}
@@ -1213,7 +1265,7 @@ prism54_get_txpower(struct net_device *n
/* intersil firmware operates in 0.25 dBm (1/4 dBm) */
vwrq->value = (s32) r.u / 4;
vwrq->fixed = 1;
- /* radio is not turned of
+ /* radio is not turned off
* btw: how is possible to turn off only the radio
*/
vwrq->disabled = 0;
@@ -1247,18 +1299,21 @@ prism54_set_txpower(struct net_device *n
}
}
-static int prism54_set_genie(struct net_device *ndev,
- struct iw_request_info *info,
- struct iw_point *data, char *extra)
+static int
+prism54_set_genie(struct net_device *ndev, struct iw_request_info *info,
+ struct iw_point *data, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
int alen, ret = 0;
struct obj_attachment *attach;
-
+
if (data->length > MAX_WPA_IE_LEN ||
(data->length && extra == NULL))
return -EINVAL;
+ if (islpci_get_state(priv) < PRV_STATE_INIT)
+ return -EINVAL;
+
memcpy(priv->wpa_ie, extra, data->length);
priv->wpa_ie_len = data->length;
@@ -1267,28 +1322,25 @@ static int prism54_set_genie(struct net_
if (attach == NULL)
return -ENOMEM;
-#define WLAN_FC_TYPE_MGMT 0
-#define WLAN_FC_STYPE_ASSOC_REQ 0
-#define WLAN_FC_STYPE_REASSOC_REQ 2
-
/* Note: endianness is covered by mgt_set_varlen */
- attach->type = (WLAN_FC_TYPE_MGMT << 2) |
- (WLAN_FC_STYPE_ASSOC_REQ << 4);
- attach->id = -1;
- attach->size = priv->wpa_ie_len;
- memcpy(attach->data, extra, priv->wpa_ie_len);
-
- ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach,
- priv->wpa_ie_len);
- if (ret == 0) {
- attach->type = (WLAN_FC_TYPE_MGMT << 2) |
- (WLAN_FC_STYPE_REASSOC_REQ << 4);
-
- ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach,
- priv->wpa_ie_len);
- if (ret == 0)
- printk(KERN_DEBUG "%s: WPA IE Attachment was set\n",
- ndev->name);
+ attach->id = -1; // global IE
+ attach->size = data->length;
+ memcpy(attach->data, extra, data->length);
+
+ if (priv->iw_mode == IW_MODE_MASTER) {
+ attach->type = DOT11_PKT_BEACON;
+ ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT,
+ attach, data->length);
+ attach->type = DOT11_PKT_PROBE_RESP;
+ ret |= mgt_set_varlen(priv, DOT11_OID_ATTACHMENT,
+ attach, data->length);
+ }
+ else {
+ attach->type = DOT11_PKT_ASSOC_REQ;
+ ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach, data->length);
+ attach->type = DOT11_PKT_REASSOC_REQ;
+ ret |= mgt_set_varlen(priv, DOT11_OID_ATTACHMENT,
+ attach, data->length);
}
kfree(attach);
@@ -1296,9 +1348,9 @@ static int prism54_set_genie(struct net_
}
-static int prism54_get_genie(struct net_device *ndev,
- struct iw_request_info *info,
- struct iw_point *data, char *extra)
+static int
+prism54_get_genie(struct net_device *ndev, struct iw_request_info *info,
+ struct iw_point *data, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
int len = priv->wpa_ie_len;
@@ -1317,38 +1369,17 @@ static int prism54_get_genie(struct net_
return 0;
}
-static int prism54_set_auth(struct net_device *ndev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
+static int
+prism54_set_auth(struct net_device *ndev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
struct iw_param *param = &wrqu->param;
- u32 mlmelevel = 0, authen = 0, dot1x = 0;
- u32 exunencrypt = 0, privinvoked = 0, wpa = 0;
- u32 old_wpa;
- int ret = 0;
- union oid_res_t r;
+ u32 set = 0;
+ int rvalue = 0;
if (islpci_get_state(priv) < PRV_STATE_INIT)
- return 0;
-
- /* first get the flags */
- down_write(&priv->mib_sem);
- wpa = old_wpa = priv->wpa;
- up_write(&priv->mib_sem);
- ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
- authen = r.u;
- ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
- privinvoked = r.u;
- ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
- exunencrypt = r.u;
- ret = mgt_get_request(priv, DOT11_OID_DOT1XENABLE, 0, NULL, &r);
- dot1x = r.u;
- ret = mgt_get_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, NULL, &r);
- mlmelevel = r.u;
-
- if (ret < 0)
- goto out;
+ return -EINVAL;
switch (param->flags & IW_AUTH_INDEX) {
case IW_AUTH_CIPHER_PAIRWISE:
@@ -1356,103 +1387,72 @@ static int prism54_set_auth(struct net_d
case IW_AUTH_KEY_MGMT:
break;
- case IW_AUTH_WPA_ENABLED:
- /* Do the same thing as IW_AUTH_WPA_VERSION */
- if (param->value) {
- wpa = 1;
- privinvoked = 1; /* For privacy invoked */
- exunencrypt = 1; /* Filter out all unencrypted frames */
- dot1x = 0x01; /* To enable eap filter */
- mlmelevel = DOT11_MLME_EXTENDED;
- authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
- } else {
- wpa = 0;
- privinvoked = 0;
- exunencrypt = 0; /* Do not filter un-encrypted data */
- dot1x = 0;
- mlmelevel = DOT11_MLME_AUTO;
- }
- break;
-
case IW_AUTH_WPA_VERSION:
- if (param->value & IW_AUTH_WPA_VERSION_DISABLED) {
- wpa = 0;
- privinvoked = 0;
- exunencrypt = 0; /* Do not filter un-encrypted data */
- dot1x = 0;
- mlmelevel = DOT11_MLME_AUTO;
- } else {
- if (param->value & IW_AUTH_WPA_VERSION_WPA)
- wpa = 1;
- else if (param->value & IW_AUTH_WPA_VERSION_WPA2)
- wpa = 2;
- privinvoked = 1; /* For privacy invoked */
- exunencrypt = 1; /* Filter out all unencrypted frames */
- dot1x = 0x01; /* To enable eap filter */
- mlmelevel = DOT11_MLME_EXTENDED;
- authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
- }
+ if (set & IW_AUTH_WPA_VERSION_WPA)
+ set = 1;
+ if (set & IW_AUTH_WPA_VERSION_WPA2)
+ set |= 2;
+ case IW_AUTH_WPA_ENABLED:
+ if (!set)
+ set = param->value ? 3 : 0;
+ rvalue = prism54_set_wpa(ndev, info, &set, extra);
break;
case IW_AUTH_RX_UNENCRYPTED_EAPOL:
- dot1x = param->value ? 1 : 0;
+ set = param->value ? 1 : 0;
+ rvalue = mgt_set_request(priv, DOT11_OID_DOT1XENABLE,
+ 0, &set);
break;
case IW_AUTH_PRIVACY_INVOKED:
- privinvoked = param->value ? 1 : 0;
+ set = param->value ? 1 : 0;
+ rvalue = mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED,
+ 0, &set);
+ break;
case IW_AUTH_DROP_UNENCRYPTED:
- exunencrypt = param->value ? 1 : 0;
+ set = param->value ? 1 : 0;
+ rvalue = mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED,
+ 0, &set);
break;
case IW_AUTH_80211_AUTH_ALG:
- if (param->value & IW_AUTH_ALG_SHARED_KEY) {
- /* Only WEP uses _SK and _BOTH */
- if (wpa > 0) {
- ret = -EINVAL;
- goto out;
- }
- authen = DOT11_AUTH_SK;
- } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
- authen = DOT11_AUTH_OS;
- } else {
- ret = -EINVAL;
- goto out;
+ switch (param->value) {
+ case IW_AUTH_ALG_OPEN_SYSTEM:
+ set = DOT11_AUTH_OS;
+ break;
+ case IW_AUTH_ALG_SHARED_KEY:
+ set = DOT11_AUTH_SK;
+ break;
+ default:
+ return -EINVAL;
+ break;
}
+ rvalue = mgt_set_request(priv, DOT11_OID_AUTHENABLE,
+ 0, &set);
break;
default:
- return -EOPNOTSUPP;
+ rvalue = -EOPNOTSUPP;
+ break;
}
- /* Set all the values */
- down_write(&priv->mib_sem);
- priv->wpa = wpa;
- up_write(&priv->mib_sem);
- mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
- mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &privinvoked);
- mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0, &exunencrypt);
- mgt_set_request(priv, DOT11_OID_DOT1XENABLE, 0, &dot1x);
- mgt_set_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, &mlmelevel);
-
-out:
- return ret;
+ return rvalue;
}
-static int prism54_get_auth(struct net_device *ndev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
+static int
+prism54_get_auth(struct net_device *ndev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
struct iw_param *param = &wrqu->param;
- u32 wpa = 0;
- int ret = 0;
union oid_res_t r;
+ u32 wpa = 0;
+ int rvalue = 0;
if (islpci_get_state(priv) < PRV_STATE_INIT)
return 0;
- /* first get the flags */
down_write(&priv->mib_sem);
wpa = priv->wpa;
up_write(&priv->mib_sem);
@@ -1464,277 +1464,292 @@ static int prism54_get_auth(struct net_d
/*
* wpa_supplicant will control these internally
*/
- ret = -EOPNOTSUPP;
- break;
+ param->value = 0;
+ return -EOPNOTSUPP;
+ break;
case IW_AUTH_WPA_VERSION:
- switch (wpa) {
- case 1:
- param->value = IW_AUTH_WPA_VERSION_WPA;
- break;
- case 2:
- param->value = IW_AUTH_WPA_VERSION_WPA2;
- break;
- case 0:
- default:
+ if (!wpa)
param->value = IW_AUTH_WPA_VERSION_DISABLED;
- break;
- }
+ if (wpa & 1)
+ param->value = IW_AUTH_WPA_VERSION_WPA;
+ if (wpa & 2)
+ param->value |= IW_AUTH_WPA_VERSION_WPA2;
+
break;
case IW_AUTH_DROP_UNENCRYPTED:
- ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
- if (ret >= 0)
- param->value = r.u > 0 ? 1 : 0;
+ rvalue = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED,
+ 0, NULL, &r);
+ param->value = r.u;
break;
case IW_AUTH_80211_AUTH_ALG:
- ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
- if (ret >= 0) {
- switch (r.u) {
- case DOT11_AUTH_OS:
- param->value = IW_AUTH_ALG_OPEN_SYSTEM;
- break;
- case DOT11_AUTH_BOTH:
- case DOT11_AUTH_SK:
- param->value = IW_AUTH_ALG_SHARED_KEY;
- case DOT11_AUTH_NONE:
- default:
- param->value = 0;
- break;
- }
+ rvalue = mgt_get_request(priv, DOT11_OID_AUTHENABLE,
+ 0, NULL, &r);
+
+ switch (r.u) {
+ case DOT11_AUTH_OS:
+ param->value = IW_AUTH_ALG_OPEN_SYSTEM;
+ break;
+ case DOT11_AUTH_BOTH:
+ case DOT11_AUTH_SK:
+ param->value = IW_AUTH_ALG_SHARED_KEY;
+ break;
+ default:
+ param->value = 0;
+ rvalue = -EOPNOTSUPP;
+ break;
}
break;
case IW_AUTH_WPA_ENABLED:
- param->value = wpa > 0 ? 1 : 0;
+ param->value = wpa ? 0 : 1;
break;
case IW_AUTH_RX_UNENCRYPTED_EAPOL:
- ret = mgt_get_request(priv, DOT11_OID_DOT1XENABLE, 0, NULL, &r);
- if (ret >= 0)
- param->value = r.u > 0 ? 1 : 0;
+ rvalue = mgt_get_request(priv, DOT11_OID_DOT1XENABLE,
+ 0, NULL, &r);
+ param->value = r.u;
break;
case IW_AUTH_PRIVACY_INVOKED:
- ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
- if (ret >= 0)
- param->value = r.u > 0 ? 1 : 0;
+ rvalue = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED,
+ 0, NULL, &r);
+ param->value = r.u;
break;
default:
return -EOPNOTSUPP;
+ break;
}
- return ret;
+
+ return 0;
}
-static int prism54_set_encodeext(struct net_device *ndev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+static int
+prism54_set_encodeext(struct net_device *ndev, struct iw_request_info *info,
+ struct iw_point *dwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
- struct iw_point *encoding = &wrqu->encoding;
- struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- int idx, alg = ext->alg, set_key = 1;
+ struct iw_encode_ext *enc = (struct iw_encode_ext *)extra;
+ struct obj_stakey* key;
union oid_res_t r;
- int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0;
- int ret = 0;
-
- if (islpci_get_state(priv) < PRV_STATE_INIT)
- return 0;
-
- /* Determine and validate the key index */
- idx = (encoding->flags & IW_ENCODE_INDEX) - 1;
- if (idx) {
- if (idx < 0 || idx > 3)
- return -EINVAL;
- } else {
- ret = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
- if (ret < 0)
- goto out;
- idx = r.u;
- }
-
- if (encoding->flags & IW_ENCODE_DISABLED)
- alg = IW_ENCODE_ALG_NONE;
+ int index, key_type;
+ int ret = -EINVAL;
- if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
- /* Only set transmit key index here, actual
- * key is set below if needed.
- */
- ret = mgt_set_request(priv, DOT11_OID_DEFKEYID, 0, &idx);
- set_key = ext->key_len > 0 ? 1 : 0;
- }
+ if ((islpci_get_state(priv) < PRV_STATE_INIT) ||
+ (enc->key_len > (dwrq->length - sizeof(*enc))) ||
+ (enc->addr.sa_family != ARPHRD_ETHER))
+ return -EINVAL;
- if (set_key) {
- struct obj_key key = { DOT11_PRIV_WEP, 0, "" };
- switch (alg) {
+ switch (enc->alg) {
case IW_ENCODE_ALG_NONE:
+ return 0;
break;
case IW_ENCODE_ALG_WEP:
- if (ext->key_len > KEY_SIZE_WEP104) {
- ret = -EINVAL;
- goto out;
- }
- if (ext->key_len > KEY_SIZE_WEP40)
- key.length = KEY_SIZE_WEP104;
- else
- key.length = KEY_SIZE_WEP40;
+ key_type = DOT11_PRIV_WEP;
break;
case IW_ENCODE_ALG_TKIP:
- if (ext->key_len > KEY_SIZE_TKIP) {
- ret = -EINVAL;
- goto out;
- }
- key.type = DOT11_PRIV_TKIP;
- key.length = KEY_SIZE_TKIP;
+ key_type = DOT11_PRIV_TKIP;
+ break;
default:
- return -EINVAL;
- }
-
- if (key.length) {
- memset(key.key, 0, sizeof(key.key));
- memcpy(key.key, ext->key, ext->key_len);
- ret = mgt_set_request(priv, DOT11_OID_DEFKEYX, idx,
- &key);
- if (ret < 0)
- goto out;
- }
+ return -EOPNOTSUPP;
}
- /* Read the flags */
- if (encoding->flags & IW_ENCODE_DISABLED) {
- /* Encoding disabled,
- * authen = DOT11_AUTH_OS;
- * invoke = 0;
- * exunencrypt = 0; */
- }
- if (encoding->flags & IW_ENCODE_OPEN) {
- /* Encode but accept non-encoded packets. No auth */
- invoke = 1;
- }
- if (encoding->flags & IW_ENCODE_RESTRICTED) {
- /* Refuse non-encoded packets. Auth */
- authen = DOT11_AUTH_BOTH;
- invoke = 1;
- exunencrypt = 1;
+ index = dwrq->flags & IW_ENCODE_INDEX;
+ if ((index < 0) || (index > 3)) {
+ /* no index provided, so get the current one */
+ ret = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
+ if (ret)
+ return ret;
+ index = r.u;
}
- /* do the change if requested */
- if (encoding->flags & IW_ENCODE_MODE) {
- ret = mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0,
- &authen);
- ret = mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0,
- &invoke);
- ret = mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0,
- &exunencrypt);
+ key = kzalloc(sizeof(*key) + enc->key_len, GFP_KERNEL);
+ if (!key)
+ return -ENOMEM;
+
+ key->type = key_type;
+ key->length = enc->key_len;
+ key->keyid = index;
+ key->reserved = 0;
+ if (!(enc->ext_flags & IW_ENCODE_EXT_GROUP_KEY))
+ key->options = DOT11_STAKEY_OPTION_DEFAULTKEY;
+ else
+ key->options = DOT11_STAKEY_OPTION_GROUPKEY;
+
+ memcpy(key->key, enc->key, key->length);
+ memcpy(key->address, enc->addr.sa_data, ETH_ALEN);
+
+ ret = mgt_set_request(priv, DOT11_OID_STAKEY, 0, key);
+ kfree(key);
+ if (ret)
+ return ret;
+
+ if (enc->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
+ struct obj_stasc *stasc;
+ stasc = kzalloc(sizeof(*stasc), GFP_KERNEL);
+ if (!stasc)
+ return -ENOMEM;
+ memcpy(stasc->address, enc->addr.sa_data, ETH_ALEN);
+ stasc->keyid = index;
+ stasc->tx_sc = 1;
+ memcpy(stasc->sc, enc->rx_seq, 6);
+ ret = mgt_set_request(priv, DOT11_OID_STASC, 0, stasc);
+ kfree(stasc);
+ if (ret)
+ return ret;
}
-out:
+ if (dwrq->flags & IW_ENCODE_MODE)
+ ret = prism54_set_auth_alg(priv, dwrq->flags);
+
return ret;
}
-
-static int prism54_get_encodeext(struct net_device *ndev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+static int
+prism54_get_encodeext(struct net_device *ndev,
+ struct iw_request_info *info, struct iw_point *dwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
- struct iw_point *encoding = &wrqu->encoding;
- struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- int idx, max_key_len;
+ struct iw_encode_ext *enc = (struct iw_encode_ext *)extra;
+ struct obj_stasc *stasc;
union oid_res_t r;
- int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0, wpa = 0;
- int ret = 0;
+ int index;
+ int ret = -EINVAL;
+ int max_key_len;
- if (islpci_get_state(priv) < PRV_STATE_INIT)
- return 0;
-
- /* first get the flags */
- ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
- authen = r.u;
- ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
- invoke = r.u;
- ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
- exunencrypt = r.u;
- if (ret < 0)
- goto out;
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
- max_key_len = encoding->length - sizeof(*ext);
+ max_key_len = dwrq->length - sizeof(*enc);
if (max_key_len < 0)
return -EINVAL;
- idx = (encoding->flags & IW_ENCODE_INDEX) - 1;
- if (idx) {
- if (idx < 0 || idx > 3)
- return -EINVAL;
- } else {
- ret = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
- if (ret < 0)
- goto out;
- idx = r.u;
- }
+ memset(enc, 0, sizeof(*enc));
- encoding->flags = idx + 1;
- memset(ext, 0, sizeof(*ext));
-
- switch (authen) {
- case DOT11_AUTH_BOTH:
- case DOT11_AUTH_SK:
- wrqu->encoding.flags |= IW_ENCODE_RESTRICTED;
- case DOT11_AUTH_OS:
- default:
- wrqu->encoding.flags |= IW_ENCODE_OPEN;
- break;
- }
+ if (islpci_get_state(priv) < PRV_STATE_INIT) {
+ dwrq->flags = IW_ENCODE_DISABLED;
+ return 0;
+ }
- down_write(&priv->mib_sem);
- wpa = priv->wpa;
- up_write(&priv->mib_sem);
+ index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
+ if ((index < 0) || (index > 3)) {
+ /* no index provided, so get the current one */
+ ret = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
+ if (ret)
+ return ret;
+ index = r.u;
+ }
- if (authen == DOT11_AUTH_OS && !exunencrypt && !invoke && !wpa) {
- /* No encryption */
- ext->alg = IW_ENCODE_ALG_NONE;
- ext->key_len = 0;
- wrqu->encoding.flags |= IW_ENCODE_DISABLED;
- } else {
+ if (enc->addr.sa_family != ARPHRD_ETHER) {
+ /* no "per-station key" */
struct obj_key *key;
-
- ret = mgt_get_request(priv, DOT11_OID_DEFKEYX, idx, NULL, &r);
- if (ret < 0)
- goto out;
+ ret = mgt_get_request(priv, DOT11_OID_DEFKEYX, index, NULL, &r);
key = r.ptr;
- if (max_key_len < key->length) {
- ret = -E2BIG;
- goto out;
+ if (ret) {
+ kfree(key);
+ return ret;
+ }
+
+ if (key->length > max_key_len) {
+ kfree(key);
+ return -E2BIG;
}
- memcpy(ext->key, key->key, key->length);
- ext->key_len = key->length;
+ enc->key_len = key->length;
switch (key->type) {
- case DOT11_PRIV_TKIP:
- ext->alg = IW_ENCODE_ALG_TKIP;
+ case DOT11_PRIV_WEP:
+ enc->alg = IW_ENCODE_ALG_WEP;
break;
+ case DOT11_PRIV_TKIP:
+ enc->alg = IW_ENCODE_ALG_TKIP;
+ break;
default:
- case DOT11_PRIV_WEP:
- ext->alg = IW_ENCODE_ALG_WEP;
+ kfree(key);
+ return -EIO;
break;
}
- wrqu->encoding.flags |= IW_ENCODE_ENABLED;
- }
-
-out:
- return ret;
-}
+ dwrq->flags |= IW_ENCODE_ENABLED;
+ memcpy(enc->key, key->key, enc->key_len);
+ dwrq->flags |= index +1;
+ return ret;
-static int
-prism54_reset(struct net_device *ndev, struct iw_request_info *info,
- __u32 * uwrq, char *extra)
-{
- islpci_reset(netdev_priv(ndev), 0);
+ }
+ else {
+ /* no "per-station key" */
+ struct obj_stakey *key;
+ key = kzalloc(sizeof(*key), GFP_KERNEL);
+ if (!key)
+ return -ENOMEM;
+
+ memcpy(key->address, enc->addr.sa_data, ETH_ALEN);
+ key->keyid = index;
+ ret = mgt_get_request(priv, DOT11_OID_STAKEY, 0, (void*)key, &r);
+ kfree(key);
+ key = (struct obj_stakey*)r.ptr;
+ if (ret) {
+ kfree(key);
+ return ret;
+ }
+
+ if (key->length > max_key_len) {
+ kfree(key);
+ return -EINVAL;
+ }
+
+ switch (key->type) {
+ case DOT11_PRIV_WEP:
+ enc->alg = IW_ENCODE_ALG_WEP;
+ break;
+ case DOT11_PRIV_TKIP:
+ enc->alg = IW_ENCODE_ALG_TKIP;
+ break;
+ default:
+ kfree(key);
+ return -EIO;
+ break;
+ }
+
+ enc->key_len = key->length;
+ dwrq->flags = index + 1;
+ memcpy(enc->key, key->key, key->length);
+ kfree(key);
+
+ /* add replay counter */
+ stasc = kzalloc(sizeof(*stasc), GFP_KERNEL);
+ if (!stasc)
+ return -ENOMEM;
+
+ memcpy(stasc->address, enc->addr.sa_data, ETH_ALEN);
+ stasc->keyid = index;
+ stasc->tx_sc = 1;
+ ret = mgt_get_request(priv, DOT11_OID_STASC, 0, (void*)stasc, &r);
+ kfree(stasc);
+ stasc = (struct obj_stasc*)r.ptr;
+ if (ret) {
+ kfree(stasc);
+ return ret;
+ }
+
+ memset(enc->tx_seq, 0, IW_ENCODE_SEQ_MAX_SIZE);
+ // prism's FW has only a 6 byte wide RSC!
+ memcpy(enc->tx_seq, stasc->sc, IW_ENCODE_SEQ_MAX_SIZE - 2);
+ enc->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID;
+ kfree(stasc);
+
+ }
+
+ return ret;
+}
+
+static int
+prism54_reset(struct net_device *ndev, struct iw_request_info *info,
+ __u32 * uwrq, char *extra)
+{
+ islpci_reset(netdev_priv(ndev), 0);
return 0;
}
@@ -2033,12 +2048,11 @@ format_event(islpci_private *priv, char
{
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 %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X [%2.2x %2.2X %4.4X]",
str,
((priv->iw_mode == IW_MODE_MASTER) ? "from" : "to"),
a[0], a[1], a[2], a[3], a[4], a[5],
- (error ? (mlme->code ? " : REJECTED " : " : ACCEPTED ")
- : ""), mlme->code);
+ mlme->state, mlme->code, mlme->id);
BUG_ON(n > IW_CUSTOM_MAX);
*length = n;
}
@@ -2104,12 +2118,6 @@ struct ieee80211_beacon_phdr {
u16 capab_info;
} __attribute__ ((packed));
-#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)
@@ -2141,10 +2149,9 @@ prism54_wpa_bss_ie_add(islpci_private *p
struct islpci_bss_wpa_ie, list);
list_del(&bss->list);
} else {
- bss = kmalloc(sizeof (*bss), GFP_ATOMIC);
+ bss = kzalloc(sizeof (*bss), GFP_ATOMIC);
if (bss != NULL) {
priv->num_bss_wpa++;
- memset(bss, 0, sizeof (*bss));
}
}
if (bss != NULL) {
@@ -2236,11 +2243,16 @@ prism54_process_bss_data(islpci_private
end = payload + len;
while (pos < end) {
if (pos + 2 + pos[1] > end) {
- printk(KERN_DEBUG "Parsing Beacon/ProbeResp failed "
- "for " MACSTR "\n", MAC2STR(addr));
+ printk(KERN_DEBUG "Parsing %s failed "
+ "for " MACSTR "\n", (oid == DOT11_OID_BEACON ? "Beacon" : "ProbeResp"), MAC2STR(addr));
return;
}
- if (pos[0] == WLAN_EID_GENERIC && pos[1] >= 4 &&
+ /* Don't forget RSN/WPA2 ! */
+ if (pos[0] == MFIE_TYPE_RSN && pos[1] > 4) {
+ prism54_wpa_bss_ie_add(priv, addr, pos, pos[1] + 2);
+ return;
+ }
+ if (pos[0] == MFIE_TYPE_GENERIC && pos[1] >= 4 &&
memcmp(pos + 2, wpa_oid, 4) == 0) {
prism54_wpa_bss_ie_add(priv, addr, pos, pos[1] + 2);
return;
@@ -2265,39 +2277,78 @@ handle_request(islpci_private *priv, str
}
static int
+prism54_process_sta_trap(islpci_private *priv, enum oid_num_t oid,
+ struct obj_mlmeex* mlmeex)
+{
+ struct obj_mlme *mlme = (struct obj_mlme*)mlmeex;
+ int ret = 0;
+
+ switch (oid) {
+ case DOT11_OID_DEAUTHENTICATEEX:
+ send_formatted_event(priv, "DeAuthenticate request",
+ mlme, 0);
+ break;
+
+ case DOT11_OID_AUTHENTICATEEX:
+ if (prism54_mac_accept(&priv->acl, mlmeex->address) &&
+ (mlmeex->state == DOT11_STATE_AUTH)) {
+
+ mlmeex->state = DOT11_STATE_ASSOCING;
+ mlmeex->code = 0;
+ mlmeex->size = 0;
+ ret = mgt_set_request(priv, DOT11_OID_ASSOCIATEEX,
+ 0, mlmeex);
+ if (ret)
+ return ret;
+ }
+ if (mlmeex->code != 0)
+ send_formatted_event(priv, "Authenticate request", mlme, 1);
+ break;
+
+ case DOT11_OID_DISASSOCIATEEX:
+ send_formatted_event(priv, "Disassociate request", mlme, 0);
+ break;
+
+ case DOT11_OID_ASSOCIATEEX:
+ if (mlmeex->code)
+ send_formatted_event(priv, "Associate request", mlme, 1);
+ break;
+
+ case DOT11_OID_REASSOCIATEEX:
+ if (mlmeex->code)
+ send_formatted_event(priv, "Reassociate request",
+ mlme, 1);
+ break;
+
+ default:
+ printk(KERN_INFO "%s: Unhandled OID %x, "
+ "please fill a bug-report!\n", priv->ndev->name, oid);
+ break;
+ }
+
+ return ret;
+}
+
+static int
prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
char *data)
{
struct obj_mlme *mlme = (struct obj_mlme *) data;
struct obj_mlmeex *mlmeex = (struct obj_mlmeex *) data;
- struct obj_mlmeex *confirm;
- u8 wpa_ie[MAX_WPA_IE_LEN];
- int wpa_ie_len;
- size_t len = 0; /* u16, better? */
- u8 *payload = NULL, *pos = NULL;
- int ret;
-
- /* I think all trapable objects are listed here.
- * Some oids have a EX version. The difference is that they are emitted
- * in DOT11_MLME_EXTENDED mode (set with DOT11_OID_MLMEAUTOLEVEL)
- * with more info.
- * The few events already defined by the wireless tools are not really
- * suited. We use the more flexible custom event facility.
- */
-
- if (oid >= DOT11_OID_BEACON) {
- len = mlmeex->size;
- payload = pos = mlmeex->data;
- }
+ int ret = 0;
/* I fear prism54_process_bss_data won't work with big endian data */
- if ((oid == DOT11_OID_BEACON) || (oid == DOT11_OID_PROBE))
- prism54_process_bss_data(priv, oid, mlmeex->address,
- payload, len);
mgt_le_to_cpu(isl_oid[oid].flags & OID_FLAG_TYPE, (void *) mlme);
switch (oid) {
+ case DOT11_OID_BEACON:
+ case DOT11_OID_PROBE:
+ if (priv->iw_mode != IW_MODE_MASTER
+ && mlmeex->state != DOT11_STATE_AUTHING)
+ prism54_process_bss_data(priv, oid, mlmeex->address,
+ mlmeex->data, mlmeex->size);
+ break;
case GEN_OID_LINKSTATE:
link_changed(priv->ndev, (u32) *data);
@@ -2330,163 +2381,12 @@ prism54_process_trap_helper(islpci_priva
send_formatted_event(priv, "ReAssociate request", mlme, 1);
break;
- case DOT11_OID_BEACON:
- send_formatted_event(priv,
- "Received a beacon from an unkown AP",
- mlme, 0);
- break;
-
- case DOT11_OID_PROBE:
- /* we received a probe from a client. */
- send_formatted_event(priv, "Received a probe from client", mlme,
- 0);
- break;
-
- /* Note : "mlme" is actually a "struct obj_mlmeex *" here, but this
- * is backward compatible layout-wise with "struct obj_mlme".
- */
-
- case DOT11_OID_DEAUTHENTICATEEX:
- send_formatted_event(priv, "DeAuthenticate request", mlme, 0);
- break;
-
- case DOT11_OID_AUTHENTICATEEX:
- handle_request(priv, mlme, oid);
- send_formatted_event(priv, "Authenticate request (ex)", mlme, 1);
-
- if (priv->iw_mode != IW_MODE_MASTER
- && mlmeex->state != DOT11_STATE_AUTHING)
- break;
-
- confirm = kmalloc(sizeof(struct obj_mlmeex) + 6, GFP_ATOMIC);
-
- 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]
- );
- confirm->id = -1; /* or mlmeex->id ? */
- confirm->state = 0; /* not used */
- confirm->code = 0;
- confirm->size = 6;
- confirm->data[0] = 0x00;
- confirm->data[1] = 0x00;
- confirm->data[2] = 0x02;
- confirm->data[3] = 0x00;
- confirm->data[4] = 0x00;
- confirm->data[5] = 0x00;
-
- ret = mgt_set_varlen(priv, DOT11_OID_ASSOCIATEEX, confirm, 6);
-
- kfree(confirm);
- if (ret)
- return ret;
- break;
-
- case DOT11_OID_DISASSOCIATEEX:
- send_formatted_event(priv, "Disassociate request (ex)", mlme, 0);
- break;
-
- case DOT11_OID_ASSOCIATEEX:
- handle_request(priv, mlme, oid);
- send_formatted_event(priv, "Associate request (ex)", mlme, 1);
-
- if (priv->iw_mode != IW_MODE_MASTER
- && mlmeex->state != DOT11_STATE_ASSOCING)
- break;
-
- confirm = kmalloc(sizeof(struct obj_mlmeex), GFP_ATOMIC);
-
- if (!confirm)
- break;
-
- memcpy(&confirm->address, mlmeex->address, ETH_ALEN);
-
- confirm->id = ((struct obj_mlmeex *)mlme)->id;
- confirm->state = 0; /* not used */
- confirm->code = 0;
-
- 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]
- );
- kfree(confirm);
- break;
- }
-
- 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;
-
- 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
- && mlmeex->state != DOT11_STATE_ASSOCING)
- break;
-
- confirm = kmalloc(sizeof(struct obj_mlmeex), GFP_ATOMIC);
-
- if (!confirm)
- break;
-
- memcpy(&confirm->address, mlmeex->address, ETH_ALEN);
-
- confirm->id = mlmeex->id;
- confirm->state = 0; /* not used */
- confirm->code = 0;
-
- 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]
- );
- kfree(confirm);
- break;
- }
-
- 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:
- return -EINVAL;
+ ret = prism54_process_sta_trap(priv, oid, mlmeex);
+ break;
}
- return 0;
+ return ret;
}
/*
@@ -2522,368 +2422,33 @@ prism54_set_mac_address(struct net_devic
return ret;
}
-/* Note: currently, use hostapd ioctl from the Host AP driver for WPA
- * support. This is to be replaced with Linux wireless extensions once they
- * get WPA support. */
-
-/* Note II: please leave all this together as it will be easier to remove later,
- * once wireless extensions add WPA support -mcgrof */
-
-/* PRISM54_HOSTAPD ioctl() cmd: */
-enum {
- PRISM2_SET_ENCRYPTION = 6,
- PRISM2_HOSTAPD_SET_GENERIC_ELEMENT = 12,
- PRISM2_HOSTAPD_MLME = 13,
- PRISM2_HOSTAPD_SCAN_REQ = 14,
-};
-
-#define PRISM54_SET_WPA SIOCIWFIRSTPRIV+12
-#define PRISM54_HOSTAPD SIOCIWFIRSTPRIV+25
-#define PRISM54_DROP_UNENCRYPTED SIOCIWFIRSTPRIV+26
-
-#define PRISM2_HOSTAPD_MAX_BUF_SIZE 1024
-#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)
- * used in ioctl() */
-#define HOSTAP_CRYPT_ALG_NAME_LEN 16
-
-struct prism2_hostapd_param {
- u32 cmd;
- u8 sta_addr[ETH_ALEN];
- union {
- struct {
- u8 alg[HOSTAP_CRYPT_ALG_NAME_LEN];
- u32 flags;
- u32 err;
- u8 idx;
- u8 seq[8]; /* sequence counter (set: RX, get: TX) */
- u16 key_len;
- u8 key[0];
- } crypt;
- struct {
- u8 len;
- u8 data[0];
- } generic_elem;
- struct {
-#define MLME_STA_DEAUTH 0
-#define MLME_STA_DISASSOC 1
- u16 cmd;
- u16 reason_code;
- } mlme;
- struct {
- u8 ssid_len;
- u8 ssid[32];
- } scan_req;
- } u;
-};
-
-
-static int
-prism2_ioctl_set_encryption(struct net_device *dev,
- struct prism2_hostapd_param *param,
- int param_len)
-{
- islpci_private *priv = netdev_priv(dev);
- int rvalue = 0, force = 0;
- int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0;
- union oid_res_t r;
-
- /* with the new API, it's impossible to get a NULL pointer.
- * New version of iwconfig set the IW_ENCODE_NOKEY flag
- * when no key is given, but older versions don't. */
-
- if (param->u.crypt.key_len > 0) {
- /* we have a key to set */
- int index = param->u.crypt.idx;
- int current_index;
- struct obj_key key = { DOT11_PRIV_TKIP, 0, "" };
-
- /* get the current key index */
- rvalue = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
- current_index = r.u;
- /* Verify that the key is not marked as invalid */
- if (!(param->u.crypt.flags & IW_ENCODE_NOKEY)) {
- key.length = param->u.crypt.key_len > sizeof (param->u.crypt.key) ?
- sizeof (param->u.crypt.key) : param->u.crypt.key_len;
- memcpy(key.key, param->u.crypt.key, key.length);
- if (key.length == 32)
- /* we want WPA-PSK */
- key.type = DOT11_PRIV_TKIP;
- if ((index < 0) || (index > 3))
- /* no index provided use the current one */
- index = current_index;
-
- /* now send the key to the card */
- rvalue |=
- mgt_set_request(priv, DOT11_OID_DEFKEYX, index,
- &key);
- }
- /*
- * 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
- */
- if ((index == current_index) && (key.length > 0))
- force = 1;
- } else {
- int index = (param->u.crypt.flags & IW_ENCODE_INDEX) - 1;
- if ((index >= 0) && (index <= 3)) {
- /* we want to set the key index */
- rvalue |=
- mgt_set_request(priv, DOT11_OID_DEFKEYID, 0,
- &index);
- } else {
- if (!param->u.crypt.flags & IW_ENCODE_MODE) {
- /* we cannot do anything. Complain. */
- return -EINVAL;
- }
- }
- }
- /* now read the flags */
- if (param->u.crypt.flags & IW_ENCODE_DISABLED) {
- /* Encoding disabled,
- * authen = DOT11_AUTH_OS;
- * invoke = 0;
- * exunencrypt = 0; */
- }
- if (param->u.crypt.flags & IW_ENCODE_OPEN)
- /* Encode but accept non-encoded packets. No auth */
- invoke = 1;
- if ((param->u.crypt.flags & IW_ENCODE_RESTRICTED) || force) {
- /* Refuse non-encoded packets. Auth */
- authen = DOT11_AUTH_BOTH;
- invoke = 1;
- exunencrypt = 1;
- }
- /* do the change if requested */
- if ((param->u.crypt.flags & IW_ENCODE_MODE) || force) {
- rvalue |=
- mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
- rvalue |=
- mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &invoke);
- rvalue |=
- mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0,
- &exunencrypt);
- }
- return rvalue;
-}
-
-static int
-prism2_ioctl_set_generic_element(struct net_device *ndev,
- struct prism2_hostapd_param *param,
- int param_len)
-{
- islpci_private *priv = netdev_priv(ndev);
- int max_len, len, alen, ret=0;
- struct obj_attachment *attach;
-
- len = param->u.generic_elem.len;
- max_len = param_len - PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN;
- if (max_len < 0 || max_len < len)
- return -EINVAL;
-
- alen = sizeof(*attach) + len;
- attach = kmalloc(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
-
- /* Note: endianness is covered by mgt_set_varlen */
-
- attach->type = (WLAN_FC_TYPE_MGMT << 2) |
- (WLAN_FC_STYPE_ASSOC_REQ << 4);
- attach->id = -1;
- attach->size = len;
- memcpy(attach->data, param->u.generic_elem.data, len);
-
- ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach, len);
-
- if (ret == 0) {
- attach->type = (WLAN_FC_TYPE_MGMT << 2) |
- (WLAN_FC_STYPE_REASSOC_REQ << 4);
-
- ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach, len);
-
- if (ret == 0)
- printk(KERN_DEBUG "%s: WPA IE Attachment was set\n",
- ndev->name);
- }
-
- kfree(attach);
- return ret;
-
-}
-
-static int
-prism2_ioctl_mlme(struct net_device *dev, struct prism2_hostapd_param *param)
-{
- return -EOPNOTSUPP;
-}
-
-static int
-prism2_ioctl_scan_req(struct net_device *ndev,
- struct prism2_hostapd_param *param)
-{
- islpci_private *priv = netdev_priv(ndev);
- int i, rvalue;
- struct obj_bsslist *bsslist;
- u32 noise = 0;
- char *extra = "";
- char *current_ev = "foo";
- union oid_res_t r;
-
- if (islpci_get_state(priv) < PRV_STATE_INIT) {
- /* device is not ready, fail gently */
- return 0;
- }
-
- /* first get the noise value. We will use it to report the link quality */
- rvalue = mgt_get_request(priv, DOT11_OID_NOISEFLOOR, 0, NULL, &r);
- noise = r.u;
-
- /* Ask the device for a list of known bss. We can report at most
- * IW_MAX_AP=64 to the range struct. 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 < min(IW_MAX_AP, (int) bsslist->nr); i++)
- current_ev = prism54_translate_bss(ndev, current_ev,
- extra + IW_SCAN_MAX_DATA,
- &(bsslist->bsslist[i]),
- noise);
- kfree(bsslist);
-
- return rvalue;
-}
-
-static int
-prism54_hostapd(struct net_device *ndev, struct iw_point *p)
-{
- struct prism2_hostapd_param *param;
- int ret = 0;
- u32 uwrq;
-
- printk(KERN_DEBUG "prism54_hostapd - len=%d\n", p->length);
- if (p->length < sizeof(struct prism2_hostapd_param) ||
- p->length > PRISM2_HOSTAPD_MAX_BUF_SIZE || !p->pointer)
- return -EINVAL;
-
- param = (struct prism2_hostapd_param *) kmalloc(p->length, GFP_KERNEL);
- if (param == NULL)
- return -ENOMEM;
-
- if (copy_from_user(param, p->pointer, p->length)) {
- kfree(param);
- return -EFAULT;
- }
-
- switch (param->cmd) {
- case PRISM2_SET_ENCRYPTION:
- printk(KERN_DEBUG "%s: Caught WPA supplicant set encryption request\n",
- ndev->name);
- ret = prism2_ioctl_set_encryption(ndev, param, p->length);
- break;
- case PRISM2_HOSTAPD_SET_GENERIC_ELEMENT:
- printk(KERN_DEBUG "%s: Caught WPA supplicant set WPA IE request\n",
- ndev->name);
- ret = prism2_ioctl_set_generic_element(ndev, param,
- p->length);
- break;
- case PRISM2_HOSTAPD_MLME:
- printk(KERN_DEBUG "%s: Caught WPA supplicant MLME request\n",
- ndev->name);
- ret = prism2_ioctl_mlme(ndev, param);
- break;
- case PRISM2_HOSTAPD_SCAN_REQ:
- printk(KERN_DEBUG "%s: Caught WPA supplicant scan request\n",
- ndev->name);
- ret = prism2_ioctl_scan_req(ndev, param);
- break;
- case PRISM54_SET_WPA:
- printk(KERN_DEBUG "%s: Caught WPA supplicant wpa init request\n",
- ndev->name);
- uwrq = 1;
- ret = prism54_set_wpa(ndev, NULL, &uwrq, NULL);
- break;
- case PRISM54_DROP_UNENCRYPTED:
- printk(KERN_DEBUG "%s: Caught WPA drop unencrypted request\n",
- ndev->name);
-#if 0
- uwrq = 0x01;
- mgt_set(priv, DOT11_OID_EXUNENCRYPTED, &uwrq);
- down_write(&priv->mib_sem);
- mgt_commit(priv);
- up_write(&priv->mib_sem);
-#endif
- /* Not necessary, as set_wpa does it, should we just do it here though? */
- ret = 0;
- break;
- default:
- printk(KERN_DEBUG "%s: Caught a WPA supplicant request that is not supported\n",
- ndev->name);
- ret = -EOPNOTSUPP;
- break;
- }
-
- if (ret == 0 && copy_to_user(p->pointer, param, p->length))
- ret = -EFAULT;
-
- kfree(param);
-
- return ret;
-}
-
static int
prism54_set_wpa(struct net_device *ndev, struct iw_request_info *info,
__u32 * uwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
- u32 mlme, authen, dot1x, filter, wep;
+ u32 mlme, dot1x;
if (islpci_get_state(priv) < PRV_STATE_INIT)
return 0;
- wep = 1; /* For privacy invoked */
- filter = 1; /* Filter out all unencrypted frames */
- dot1x = 0x01; /* To enable eap filter */
- mlme = DOT11_MLME_EXTENDED;
- authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
+ dot1x = 0; // disable global filtering
+ mlme = DOT11_MLME_AUTO;
down_write(&priv->mib_sem);
priv->wpa = *uwrq;
- switch (priv->wpa) {
- default:
- case 0: /* Clears/disables WPA and friends */
- wep = 0;
- filter = 0; /* Do not filter un-encrypted data */
- dot1x = 0;
- mlme = DOT11_MLME_AUTO;
- printk("%s: Disabling WPA\n", ndev->name);
- break;
- case 2:
- case 1: /* WPA */
- printk("%s: Enabling WPA\n", ndev->name);
- break;
+ if (priv->wpa) {
+ if (priv->iw_mode == IW_MODE_MASTER)
+ dot1x = 1;
+ mlme = DOT11_MLME_EXTENDED;
}
up_write(&priv->mib_sem);
- mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
- mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &wep);
- mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0, &filter);
mgt_set_request(priv, DOT11_OID_DOT1XENABLE, 0, &dot1x);
mgt_set_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, &mlme);
- return 0;
+ return prism54_set_auth_alg(priv, IW_ENCODE_OPEN);
}
static int
@@ -2891,7 +2456,9 @@ prism54_get_wpa(struct net_device *ndev,
__u32 * uwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
+ down_write(&priv->mib_sem);
*uwrq = priv->wpa;
+ up_write(&priv->mib_sem);
return 0;
}
@@ -3026,6 +2593,80 @@ prism54_set_spy(struct net_device *ndev,
return iw_handler_set_spy(ndev, info, uwrq, extra);
}
+static int
+prism54_send_mlme(struct net_device *ndev, struct iw_request_info *info,
+ struct iw_point *dwrq, char *extra)
+{
+ islpci_private *priv = netdev_priv(ndev);
+ struct iw_mlme *iwmlme;
+ struct obj_mlme mlme;
+ struct obj_sta *sta;
+ union oid_res_t r;
+ int ret = 0;
+
+ if (dwrq->length != sizeof(*iwmlme))
+ return -EINVAL;
+
+ iwmlme = (struct iw_mlme*)extra;
+
+ if (iwmlme->addr.sa_family != ARPHRD_ETHER)
+ return -EINVAL;
+
+ /* get STA/AP Id.
+ or the card will BROADCAST the mgmt packets! */
+
+ sta = (struct obj_sta*)kzalloc(sizeof(*sta), GFP_KERNEL);
+ if (!sta)
+ return -ENOMEM;
+
+ memcpy(sta->address, iwmlme->addr.sa_data, ETH_ALEN);
+ ret = mgt_get_request(priv, DOT11_OID_CLIENTFIND, 0, sta, &r);
+ kfree(sta);
+
+ if (ret) {
+ sta = r.ptr;
+ memcpy(mlme.address, iwmlme->addr.sa_data, ETH_ALEN);
+
+ if (sta->node >= 1)
+ mlme.id = sta->node;
+ else
+ mlme.id = -1;
+ } else
+ /* use broadcast id */
+ mlme.id = -1;
+
+ mlme.code = iwmlme->reason_code;
+
+ kfree(r.ptr);
+ switch (iwmlme->cmd) {
+ case IW_MLME_DEAUTH:
+ mlme.state = DOT11_STATE_NONE;
+ return mgt_set_request(priv, DOT11_OID_DEAUTHENTICATE,
+ 0, &mlme);
+ break;
+ case IW_MLME_DISASSOC:
+ mlme.state = DOT11_STATE_NONE;
+ return mgt_set_request(priv, DOT11_OID_DISASSOCIATE,
+ 0, &mlme);
+ break;
+#if 0
+ /* not in WEXT yet */
+ case IW_MLME_AUTH:
+ mlme.state = DOT11_STATE_AUTH;
+ return mgt_set_request(priv, DOT11_OID_AUTHENTICATE,
+ 0, &mlme);
+ break;
+ case IW_MLME_ASSOC:
+ mlme.state = DOT11_STATE_ASSOC;
+ return mgt_set_request(priv, DOT11_OID_ASSOCIATE,
+ 0, &mlme);
+ break;
+#endif
+ }
+
+ return -EOPNOTSUPP;
+}
+
static const iw_handler prism54_handler[] = {
(iw_handler) prism54_commit, /* SIOCSIWCOMMIT */
(iw_handler) prism54_get_name, /* SIOCGIWNAME */
@@ -3049,7 +2690,7 @@ static const iw_handler prism54_handler[
iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
(iw_handler) prism54_set_wap, /* SIOCSIWAP */
(iw_handler) prism54_get_wap, /* SIOCGIWAP */
- (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) prism54_send_mlme, /* SIOCSIWMLME */
(iw_handler) NULL, /* SIOCGIWAPLIST depreciated */
(iw_handler) prism54_set_scan, /* SIOCSIWSCAN */
(iw_handler) prism54_get_scan, /* SIOCGIWSCAN */
@@ -3073,15 +2714,15 @@ static const iw_handler prism54_handler[
(iw_handler) prism54_get_encode, /* SIOCGIWENCODE */
(iw_handler) NULL, /* SIOCSIWPOWER */
(iw_handler) NULL, /* SIOCGIWPOWER */
- NULL, /* -- hole -- */
- NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
(iw_handler) prism54_set_genie, /* SIOCSIWGENIE */
(iw_handler) prism54_get_genie, /* SIOCGIWGENIE */
(iw_handler) prism54_set_auth, /* SIOCSIWAUTH */
(iw_handler) prism54_get_auth, /* SIOCGIWAUTH */
- (iw_handler) prism54_set_encodeext, /* SIOCSIWENCODEEXT */
- (iw_handler) prism54_get_encodeext, /* SIOCGIWENCODEEXT */
- NULL, /* SIOCSIWPMKSA */
+ (iw_handler) prism54_set_encodeext, /* SIOCSIWENCODEEXT */
+ (iw_handler) prism54_get_encodeext, /* SIOCGIWENCODEEXT */
+ (iw_handler) NULL /* SIOCSIWPMKSA */
};
/* The low order bit identify a SET (0) or a GET (1) ioctl. */
@@ -3260,14 +2901,5 @@ const struct iw_handler_def prism54_hand
int
prism54_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
{
- struct iwreq *wrq = (struct iwreq *) rq;
- int ret = -1;
- switch (cmd) {
- case PRISM54_HOSTAPD:
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- ret = prism54_hostapd(ndev, &wrq->u.data);
- return ret;
- }
return -EOPNOTSUPP;
}
diff -Nurp a/drivers/net/wireless/prism54/isl_ioctl.h b/drivers/net/wireless/prism54/isl_ioctl.h
--- a/drivers/net/wireless/prism54/isl_ioctl.h 2006-09-28 21:13:25.000000000 +0200
+++ b/drivers/net/wireless/prism54/isl_ioctl.h 2006-10-02 20:26:37.000000000 +0200
@@ -22,12 +22,11 @@
#ifndef _ISL_IOCTL_H
#define _ISL_IOCTL_H
+#include <net/iw_handler.h> /* New driver API */
#include "islpci_mgt.h"
#include "islpci_dev.h"
-#include <net/iw_handler.h> /* New driver API */
-
-#define SUPPORTED_WIRELESS_EXT 19
+#define SUPPORTED_WIRELESS_EXT 21
void prism54_mib_init(islpci_private *);
@@ -48,4 +47,5 @@ int prism54_ioctl(struct net_device *, s
extern const struct iw_handler_def prism54_handler_def;
+
#endif /* _ISL_IOCTL_H */
diff -Nurp a/drivers/net/wireless/prism54/isl_oid.h b/drivers/net/wireless/prism54/isl_oid.h
--- a/drivers/net/wireless/prism54/isl_oid.h 2006-09-20 05:42:06.000000000 +0200
+++ b/drivers/net/wireless/prism54/isl_oid.h 2006-10-03 14:26:22.000000000 +0200
@@ -4,6 +4,7 @@
* Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
* Copyright (C) 2004 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
* Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
+ * Copyright (C) 2006 Christian Lamparter <chunkeey@web.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,6 +29,8 @@
* with the device firmware
*/
+#define MAX_KEY_LEN 32
+
struct obj_ssid {
u8 length;
char octets[33];
@@ -36,18 +39,28 @@ struct obj_ssid {
struct obj_key {
u8 type; /* dot11_priv_t */
u8 length;
- char key[32];
+ char key[MAX_KEY_LEN];
+} __attribute__ ((packed));
+
+struct obj_stakey {
+ u8 address[ETH_ALEN];
+ u8 keyid;
+ u8 reserved;
+ u16 options; // dot11_stakey_opt_t
+ u8 type; /* dot11_priv_t */
+ u8 length;
+ char key[MAX_KEY_LEN];
} __attribute__ ((packed));
struct obj_mlme {
- u8 address[6];
+ u8 address[ETH_ALEN];
u16 id;
u16 state;
u16 code;
} __attribute__ ((packed));
struct obj_mlmeex {
- u8 address[6];
+ u8 address[ETH_ALEN];
u16 id;
u16 state;
u16 code;
@@ -61,7 +74,7 @@ struct obj_buffer {
} __attribute__ ((packed));
struct obj_bss {
- u8 address[6];
+ u8 address[ETH_ALEN];
int:16; /* padding */
char state;
@@ -99,6 +112,25 @@ struct obj_attachment {
char data[0];
} __attribute__((packed));
+struct obj_stasc {
+ char address[ETH_ALEN];
+ char keyid;
+ char tx_sc;
+ char sc[6];
+} __attribute__ ((packed));
+
+struct obj_sta {
+ u8 address[ETH_ALEN];
+ int: 16;
+ u8 state;
+ u8 node; // STA ID
+ u16 age;
+ u8 reserved1;
+ u8 rssi;
+ u8 rate;
+ u8 reserved2;
+} __attribute__ ((packed));
+
/*
* in case everything's ok, the inlined function below will be
* optimized away by the compiler...
@@ -114,6 +146,10 @@ __bug_on_wrong_struct_sizes(void)
BUG_ON(sizeof (struct obj_bss) != 60);
BUG_ON(sizeof (struct obj_bsslist) != 4);
BUG_ON(sizeof (struct obj_frequencies) != 2);
+ BUG_ON(sizeof (struct obj_sta) != 16);
+ BUG_ON(sizeof (struct obj_stasc) != 14);
+ BUG_ON(sizeof (struct obj_stakey) != 44);
+ BUG_ON(sizeof (struct obj_attachment) != 6);
}
enum dot11_state_t {
@@ -121,7 +157,7 @@ enum dot11_state_t {
DOT11_STATE_AUTHING = 1,
DOT11_STATE_AUTH = 2,
DOT11_STATE_ASSOCING = 3,
-
+ DOT11_STATE_REASSOC = 4,
DOT11_STATE_ASSOC = 5,
DOT11_STATE_IBSS = 6,
DOT11_STATE_WDS = 7
@@ -466,31 +502,32 @@ enum oid_num_t {
OID_NUM_LAST
};
-#define OID_FLAG_CACHED 0x80
-#define OID_FLAG_TYPE 0x7f
-
-#define OID_TYPE_U32 0x01
-#define OID_TYPE_SSID 0x02
-#define OID_TYPE_KEY 0x03
-#define OID_TYPE_BUFFER 0x04
-#define OID_TYPE_BSS 0x05
-#define OID_TYPE_BSSLIST 0x06
-#define OID_TYPE_FREQUENCIES 0x07
-#define OID_TYPE_MLME 0x08
-#define OID_TYPE_MLMEEX 0x09
-#define OID_TYPE_ADDR 0x0A
-#define OID_TYPE_RAW 0x0B
-#define OID_TYPE_ATTACH 0x0C
+enum oid_types_t {
+ OID_TYPE_U32 = 0x01,
+ OID_TYPE_SSID = 0x02,
+ OID_TYPE_KEY = 0x03,
+ OID_TYPE_BUFFER = 0x04,
+ OID_TYPE_BSS = 0x05,
+ OID_TYPE_BSSLIST = 0x06,
+ OID_TYPE_FREQUENCIES = 0x07,
+ OID_TYPE_MLME = 0x08,
+ OID_TYPE_MLMEEX = 0x09,
+ OID_TYPE_ADDR = 0x0A,
+ OID_TYPE_RAW = 0x0B,
+ OID_TYPE_ATTACH = 0x0C,
+ OID_TYPE_STASC = 0x0D,
+ OID_TYPE_STAKEY = 0x0E,
+ OID_TYPE_STAINFO = 0x0F,
-/* OID_TYPE_MLMEEX is special because of a variable size field when sending.
- * Not yet implemented (not used in driver anyway).
- */
+ OID_FLAG_CACHED = 0x80,
+ OID_FLAG_TYPE = 0x7f
+};
struct oid_t {
enum oid_num_t oid;
short range; /* to define a range of oid */
short size; /* max size of the associated data */
- char flags;
+ enum oid_types_t flags;
};
union oid_res_t {
@@ -503,5 +540,19 @@ union oid_res_t {
#define IWMAX_FREQ 30
#define PRIV_STR_SIZE 1024
+enum dot11_pkt_t {
+ DOT11_PKT_ASSOC_REQ = 0x00,
+ DOT11_PKT_ASSOC_RESP = 0x10,
+ DOT11_PKT_REASSOC_REQ = 0x20,
+ DOT11_PKT_REASSOC_RESP = 0x30,
+ DOT11_PKT_PROBE_RESP = 0x50,
+ DOT11_PKT_BEACON = 0x80
+};
+
+enum dot11_stakey_opt_t {
+ DOT11_STAKEY_OPTION_GROUPKEY = 0x0000,
+ DOT11_STAKEY_OPTION_DEFAULTKEY = 0x0001
+};
+
#endif /* !defined(_ISL_OID_H) */
/* EOF */
diff -Nurp a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
--- a/drivers/net/wireless/prism54/islpci_dev.c 2006-09-28 21:13:25.000000000 +0200
+++ b/drivers/net/wireless/prism54/islpci_dev.c 2006-09-28 23:42:47.000000000 +0200
@@ -453,6 +453,7 @@ islpci_upload_fw(islpci_private *priv)
printk(KERN_DEBUG "%s: uploading firmware...\n", priv->ndev->name);
+ request_module("firmware_class");
rc = isl_upload_firmware(priv);
if (rc) {
/* error uploading the firmware */
diff -Nurp a/drivers/net/wireless/prism54/islpci_hotplug.c b/drivers/net/wireless/prism54/islpci_hotplug.c
--- a/drivers/net/wireless/prism54/islpci_hotplug.c 2006-09-28 21:13:25.000000000 +0200
+++ b/drivers/net/wireless/prism54/islpci_hotplug.c 2006-10-03 12:41:59.000000000 +0200
@@ -171,7 +171,10 @@ prism54_probe(struct pci_dev *pdev, cons
pci_set_master(pdev);
/* enable MWI */
- pci_set_mwi(pdev);
+ if (pci_set_mwi(pdev)) {
+ printk(KERN_ERR "%s: could not enabke MWI\n", DRV_NAME);
+ goto do_pci_release_regions;
+ }
/* setup the network device interface and its structure */
if (!(ndev = islpci_setup(pdev))) {
@@ -290,7 +293,11 @@ prism54_resume(struct pci_dev *pdev)
islpci_private *priv = ndev ? netdev_priv(ndev) : NULL;
BUG_ON(!priv);
- pci_enable_device(pdev);
+ // what can we do, if pci_enable_device fails?
+ if (pci_enable_device(pdev) < 0) {
+ printk(KERN_ERR "%s: pci_enable_device() failed.\n", DRV_NAME);
+ return -ENODEV;
+ }
printk(KERN_NOTICE "%s: got resume request\n", ndev->name);
diff -Nurp a/drivers/net/wireless/prism54/islpci_mgt.h b/drivers/net/wireless/prism54/islpci_mgt.h
--- a/drivers/net/wireless/prism54/islpci_mgt.h 2006-09-20 05:42:06.000000000 +0200
+++ b/drivers/net/wireless/prism54/islpci_mgt.h 2006-09-29 14:22:05.000000000 +0200
@@ -65,8 +65,8 @@ extern int pc_debug;
#define CARD_DEFAULT_WEP 0
#define CARD_DEFAULT_FILTER 0
#define CARD_DEFAULT_WDS 0
-#define CARD_DEFAULT_AUTHEN DOT11_AUTH_OS
-#define CARD_DEFAULT_DOT1X 0
+#define CARD_DEFAULT_AUTHEN DOT11_AUTH_OS
+#define CARD_DEFAULT_DOT1X 0
#define CARD_DEFAULT_MLME_MODE DOT11_MLME_AUTO
#define CARD_DEFAULT_CONFORMANCE OID_INL_CONFORMANCE_NONE
#define CARD_DEFAULT_PROFILE DOT11_PROFILE_MIXED_G_WIFI
diff -Nurp a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c
--- a/drivers/net/wireless/prism54/oid_mgt.c 2006-09-20 05:42:06.000000000 +0200
+++ b/drivers/net/wireless/prism54/oid_mgt.c 2006-10-03 12:33:09.000000000 +0200
@@ -59,7 +59,7 @@ struct oid_t isl_oid[] = {
OID_UNKNOWN(GEN_OID_MIBOP, 0x00000003),
OID_UNKNOWN(GEN_OID_OPTIONS, 0x00000004),
OID_UNKNOWN(GEN_OID_LEDCONFIG, 0x00000005),
-
+
/* 802.11 */
OID_U32_C(DOT11_OID_BSSTYPE, 0x10000000),
OID_STRUCT_C(DOT11_OID_BSSID, 0x10000001, u8[6], OID_TYPE_RAW),
@@ -85,9 +85,9 @@ struct oid_t isl_oid[] = {
OID_U32_C(DOT11_OID_DEFKEYID, 0x12000003),
[DOT11_OID_DEFKEYX] = {0x12000004, 3, sizeof (struct obj_key),
OID_FLAG_CACHED | OID_TYPE_KEY}, /* DOT11_OID_DEFKEY1,...DOT11_OID_DEFKEY4 */
- OID_UNKNOWN(DOT11_OID_STAKEY, 0x12000008),
+ OID_STRUCT(DOT11_OID_STAKEY, 0x12000008, struct obj_stakey, OID_TYPE_STAKEY),
OID_U32(DOT11_OID_REKEYTHRESHOLD, 0x12000009),
- OID_UNKNOWN(DOT11_OID_STASC, 0x1200000a),
+ OID_STRUCT(DOT11_OID_STASC, 0x1200000a, struct obj_stasc, OID_TYPE_STASC),
OID_U32(DOT11_OID_PRIVTXREJECTED, 0x1a000000),
OID_U32(DOT11_OID_PRIVRXPLAIN, 0x1a000001),
@@ -122,9 +122,9 @@ struct oid_t isl_oid[] = {
OID_U32(DOT11_OID_BRIDGELOCAL, 0x15000000),
OID_U32(DOT11_OID_CLIENTS, 0x15000001),
OID_U32(DOT11_OID_CLIENTSASSOCIATED, 0x15000002),
- [DOT11_OID_CLIENTX] = {0x15000003, 2006, 0, 0}, /* DOT11_OID_CLIENTX,...DOT11_OID_CLIENT2007 */
+ [DOT11_OID_CLIENTX] = {0x15000003, 2006, sizeof(struct obj_sta), OID_TYPE_STAINFO}, /* DOT11_OID_CLIENTX,...DOT11_OID_CLIENT2007 */
- OID_STRUCT(DOT11_OID_CLIENTFIND, 0x150007DB, u8[6], OID_TYPE_ADDR),
+ OID_STRUCT(DOT11_OID_CLIENTFIND, 0x150007DB, struct obj_sta, OID_TYPE_STAINFO),
OID_STRUCT(DOT11_OID_WDSLINKADD, 0x150007DC, u8[6], OID_TYPE_ADDR),
OID_STRUCT(DOT11_OID_WDSLINKREMOVE, 0x150007DD, u8[6], OID_TYPE_ADDR),
OID_STRUCT(DOT11_OID_EAPAUTHSTA, 0x150007DE, u8[6], OID_TYPE_ADDR),
@@ -201,8 +201,7 @@ struct oid_t isl_oid[] = {
OID_U32(DOT11_OID_STATIMEOUT, 0x19000000),
OID_U32_C(DOT11_OID_MLMEAUTOLEVEL, 0x19000001),
OID_U32(DOT11_OID_BSSTIMEOUT, 0x19000002),
- [DOT11_OID_ATTACHMENT] = {0x19000003, 0,
- sizeof(struct obj_attachment), OID_TYPE_ATTACH},
+ OID_STRUCT_C(DOT11_OID_ATTACHMENT, 0x19000003, sizeof(struct obj_attachment), OID_TYPE_ATTACH),
OID_STRUCT_C(DOT11_OID_PSMBUFFER, 0x19000004, struct obj_buffer,
OID_TYPE_BUFFER),
@@ -277,7 +276,7 @@ mgt_clean(islpci_private *priv)
}
void
-mgt_le_to_cpu(int type, void *data)
+mgt_le_to_cpu(enum oid_types_t type, void *data)
{
switch (type) {
case OID_TYPE_U32:
@@ -334,19 +333,31 @@ mgt_le_to_cpu(int type, void *data)
attach->id = le16_to_cpu(attach->id);
attach->size = le16_to_cpu(attach->size);
break;
- }
+ }
+ case OID_TYPE_STAKEY: {
+ struct obj_stakey *stakey = data;
+ stakey->options = le16_to_cpu(stakey->options);
+ break;
+ }
+ case OID_TYPE_STAINFO: {
+ struct obj_sta *sta = data;
+ sta->age = le16_to_cpu(sta->age);
+ break;
+ }
case OID_TYPE_SSID:
case OID_TYPE_KEY:
case OID_TYPE_ADDR:
case OID_TYPE_RAW:
+ case OID_TYPE_STASC:
break;
default:
BUG();
+ break;
}
}
static void
-mgt_cpu_to_le(int type, void *data)
+mgt_cpu_to_le(enum oid_types_t type, void *data)
{
switch (type) {
case OID_TYPE_U32:
@@ -403,14 +414,26 @@ mgt_cpu_to_le(int type, void *data)
attach->id = cpu_to_le16(attach->id);
attach->size = cpu_to_le16(attach->size);
break;
- }
+ }
+ case OID_TYPE_STAKEY: {
+ struct obj_stakey *stakey = data;
+ stakey->options = cpu_to_le16(stakey->options);
+ break;
+ }
+ case OID_TYPE_STAINFO: {
+ struct obj_sta *sta = data;
+ sta->age = cpu_to_le16(sta->age);
+ break;
+ }
case OID_TYPE_SSID:
case OID_TYPE_KEY:
case OID_TYPE_ADDR:
case OID_TYPE_RAW:
+ case OID_TYPE_STASC:
break;
default:
BUG();
+ break;
}
}
@@ -658,13 +681,16 @@ static enum oid_num_t commit_part1[] = {
static enum oid_num_t commit_part2[] = {
DOT11_OID_SSID,
+ /* unstable with WPA
DOT11_OID_PSMBUFFER,
+ */
DOT11_OID_AUTHENABLE,
DOT11_OID_PRIVACYINVOKED,
DOT11_OID_EXUNENCRYPTED,
DOT11_OID_DEFKEYX, /* MULTIPLE */
DOT11_OID_DEFKEYID,
DOT11_OID_DOT1XENABLE,
+ DOT11_OID_ATTACHMENT,
OID_INL_DOT11D_CONFORMANCE,
/* Do not initialize this - fw < 1.0.4.3 rejects it
OID_INL_OUTPUTPOWER,
diff -Nurp a/drivers/net/wireless/prism54/oid_mgt.h b/drivers/net/wireless/prism54/oid_mgt.h
--- a/drivers/net/wireless/prism54/oid_mgt.h 2006-09-20 05:42:06.000000000 +0200
+++ b/drivers/net/wireless/prism54/oid_mgt.h 2006-09-29 20:25:17.000000000 +0200
@@ -32,7 +32,7 @@ void mgt_clean(islpci_private *);
extern const int frequency_list_a[];
int channel_of_freq(int);
-void mgt_le_to_cpu(int, void *);
+void mgt_le_to_cpu(enum oid_types_t, void *);
int mgt_set_request(islpci_private *, enum oid_num_t, int, void *);
int mgt_set_varlen(islpci_private *, enum oid_num_t, void *, int);
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH] prism54: wpa support for fullmac cards
2006-10-03 12:57 [PATCH] prism54: wpa support for fullmac cards chunkeey
@ 2006-10-04 10:38 ` Jiri Benc
2006-10-04 11:40 ` Dan Williams
2006-10-17 21:32 ` John W. Linville
1 sibling, 1 reply; 39+ messages in thread
From: Jiri Benc @ 2006-10-04 10:38 UTC (permalink / raw)
To: chunkeey; +Cc: netdev
On Tue, 3 Oct 2006 14:57:33 +0200, chunkeey@web.de wrote:
> This patch (prism54-en-wpa3.patch) brings WPA/WPA2(RSN) with
> TKIP-Cipher to everyone with a FULLMAC Prism GT/Indigo/Duette card.
> I removed all the parts(e.g.: Hostapd Support) which are not relevant for
> wpa_supplicant (client/managed mode).
Are you proposing a patch that removes AP support from the driver or did
I understand it wrong?
Thanks,
Jiri
--
Jiri Benc
SUSE Labs
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH] prism54: wpa support for fullmac cards
2006-10-04 10:38 ` Jiri Benc
@ 2006-10-04 11:40 ` Dan Williams
2006-10-04 14:12 ` chunkeey
0 siblings, 1 reply; 39+ messages in thread
From: Dan Williams @ 2006-10-04 11:40 UTC (permalink / raw)
To: Jiri Benc; +Cc: chunkeey, netdev
On Wed, 2006-10-04 at 12:38 +0200, Jiri Benc wrote:
> On Tue, 3 Oct 2006 14:57:33 +0200, chunkeey@web.de wrote:
> > This patch (prism54-en-wpa3.patch) brings WPA/WPA2(RSN) with
> > TKIP-Cipher to everyone with a FULLMAC Prism GT/Indigo/Duette card.
> > I removed all the parts(e.g.: Hostapd Support) which are not relevant for
> > wpa_supplicant (client/managed mode).
>
> Are you proposing a patch that removes AP support from the driver or did
> I understand it wrong?
I believe it adds the support back in, just using standard WE ioctls
like ENCODEEXT and AUTH rather than the custom HostAP ones... which
brings up the question whether the hostapd driver for wext (is there
such a thing?) works well enough.
Dan
> Thanks,
>
> Jiri
>
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH] prism54: wpa support for fullmac cards
2006-10-04 11:40 ` Dan Williams
@ 2006-10-04 14:12 ` chunkeey
2006-10-04 21:43 ` Jouni Malinen
0 siblings, 1 reply; 39+ messages in thread
From: chunkeey @ 2006-10-04 14:12 UTC (permalink / raw)
To: Dan Williams; +Cc: netdev, chunkeey
On Wed, 4 Oct 2006 13:40 +0200 dcbw@redhat.com wrote:
> On Wed, 2006-10-04 at 12:38 +0200, Jiri Benc wrote:
> > On Tue, 3 Oct 2006 14:57:33 +0200, chunkeey@web.de wrote:
> > > This patch (prism54-en-wpa3.patch) brings WPA/WPA2(RSN) with
> > > TKIP-Cipher to everyone with a FULLMAC Prism GT/Indigo/Duette card.
> > > I removed all the parts(e.g.: Hostapd Support) which are not relevant
> > > for wpa_supplicant (client/managed mode).
> >
> > Are you proposing a patch that removes AP support from the driver or did
> > I understand it wrong?
>
> I believe it adds the support back in, just using standard WE ioctls
> like ENCODEEXT and AUTH rather than the custom HostAP ones... which
> brings up the question whether the hostapd driver for wext (is there
> such a thing?) works well enough.
>
> Dan
>
the AP code never worked. And the hostapd-ioctl interface was designed
for prism2/2.5/3 cards, but not for "fullmac" prism54.
Because the "fullmac" prism54 card does everything(mac-, key- and
station-management) in the firmware and the hostapd_param struct
does neither support the necessary mlme requests/responses (Authentication &
Association frames) nor a param to handle the EAP filter for the stations.
(I wrote a "patch" HostAPD support, but with it's own
firmwareap_param struct and some other hacky things, but it works well.
I can post a diff too, but "be" warned! ;) )
(BTW, hostapd's backend for prism54 uses a "proprietary" interface -
PIMFOR -, which never made it into the kernel.)
Chr.
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH] prism54: wpa support for fullmac cards
2006-10-04 14:12 ` chunkeey
@ 2006-10-04 21:43 ` Jouni Malinen
2006-10-05 17:17 ` chunkeey
0 siblings, 1 reply; 39+ messages in thread
From: Jouni Malinen @ 2006-10-04 21:43 UTC (permalink / raw)
To: chunkeey; +Cc: Dan Williams, netdev
On Wed, Oct 04, 2006 at 04:12:26PM +0200, chunkeey@web.de wrote:
> the AP code never worked. And the hostapd-ioctl interface was designed
> for prism2/2.5/3 cards, but not for "fullmac" prism54.
What do you mean by never working? I have seen fullmac Prism54
completing WPA authentication with hostapd.. This was using the
driver_prism54.c in hostapd, not the Host AP driver interface.
> (BTW, hostapd's backend for prism54 uses a "proprietary" interface -
> PIMFOR -, which never made it into the kernel.)
But it worked in the external driver. So yes, saying that the version in
kernel tree never worked in AP mode would probably be valid.
And as far as the WEXT interface in hostapd is concerned, no, there is
no such thing yet.
--
Jouni Malinen PGP id EFC895FA
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH] prism54: wpa support for fullmac cards
2006-10-04 21:43 ` Jouni Malinen
@ 2006-10-05 17:17 ` chunkeey
0 siblings, 0 replies; 39+ messages in thread
From: chunkeey @ 2006-10-05 17:17 UTC (permalink / raw)
To: Jouni Malinen; +Cc: chunkeey, netdev
On Wed, Oct 04, 2006 23:43 you wrote:
> On Wed, Oct 04, 2006 at 04:12:26PM +0200, chunkeey@web.de wrote:
> > the AP code never worked. And the hostapd-ioctl interface was designed
> > for prism2/2.5/3 cards, but not for "fullmac" prism54.
>
> What do you mean by never working? I have seen fullmac Prism54
> completing WPA authentication with hostapd.. This was using the
> driver_prism54.c in hostapd, not the Host AP driver interface.
> > (BTW, hostapd's backend for prism54 uses a "proprietary" interface -
> > PIMFOR -, which never made it into the kernel.)
>
> But it worked in the external driver. So yes, saying that the version in
> kernel tree never worked in AP mode would probably be valid.
>
ok, sorry my fault, I should have put it this was:
it was never woking for ME, linmax, roland warsow, ...
and I tried alot of things. (patches, how-tos, ask the maintainer, etc. )
But i only saw "Oops" or "mgt: queue full" ...
the PIMFOR-Interface is a direct "tunnel" to the hardware.
And guess what? it's very "crashy" .. (e.g "set/get the generic elements" does
a very good job. ;) )
> And as far as the WEXT interface in hostapd is concerned, no, there is
> no such thing yet.
that's correct.
WEXT is not going anywhere anymore, but maybe cfg80211?
Chr
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH] prism54: wpa support for fullmac cards
2006-10-03 12:57 [PATCH] prism54: wpa support for fullmac cards chunkeey
2006-10-04 10:38 ` Jiri Benc
@ 2006-10-17 21:32 ` John W. Linville
2006-10-29 12:35 ` [PATCH wireless-2.6-git] prism54: WPA/RSN " chunkeey
1 sibling, 1 reply; 39+ messages in thread
From: John W. Linville @ 2006-10-17 21:32 UTC (permalink / raw)
To: chunkeey; +Cc: netdev
On Tue, Oct 03, 2006 at 02:57:33PM +0200, chunkeey@web.de wrote:
> This patch (prism54-en-wpa3.patch) brings WPA/WPA2(RSN) with
> TKIP-Cipher to everyone with a FULLMAC Prism GT/Indigo/Duette card.
> I removed all the parts(e.g.: Hostapd Support) which are not relevant for
> wpa_supplicant (client/managed mode).
>
> now, you can connect to your WLAN with:
> wpa_supplicant -Dwext -c{WPA_CONF} -i{WPA_ETH} -dd
>
> This code is just for review & testers...
> so only a pre-signed-off for now. ;)
> Pre- Signed-off-by: Christian Lamparter <chunkeey@web.de>
I apologize for the late response.
I was going to include this patch in my pending branch, but I can't
get it to apply. The rejects are a bit big for me to hand-resolve.
Please review the patch posting procedures documented here:
http://linux.yyz.us/patch-format.html
Feel free to resubmit the patch, based of the current wireless-2.6 tree:
git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git
Thanks,
John
--
John W. Linville
linville@tuxdriver.com
^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
2006-10-17 21:32 ` John W. Linville
@ 2006-10-29 12:35 ` chunkeey
2006-10-30 8:50 ` Johannes Berg
` (2 more replies)
0 siblings, 3 replies; 39+ messages in thread
From: chunkeey @ 2006-10-29 12:35 UTC (permalink / raw)
To: John W. Linville; +Cc: netdev
[-- Attachment #1: Type: text/plain, Size: 369 bytes --]
This patch completes WPA/RSN with TKIP support for all fullmac prism54 cards.
I removed all parts which are not relevant for wpa_supplicant (managed mode).
you can connect to your WLAN with:
wpa_supplicant -Dwext -c{WPA_CONF} -i{WPA_ETH}
Signed-off-by: Christian Lamparter <chunkeey@web.de>
off-topic:
Can someone please check my changelog for spelling "errors"?
[-- Attachment #2: prism-wpa-wl26git.patch --]
[-- Type: text/x-diff, Size: 72679 bytes --]
diff --git a/drivers/net/wireless/prism54/isl_38xx.c b/drivers/net/wireless/prism54/isl_38xx.c
index 02fc67b..044a23f 100644
--- a/drivers/net/wireless/prism54/isl_38xx.c
+++ b/drivers/net/wireless/prism54/isl_38xx.c
@@ -24,7 +24,6 @@ #include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/io.h>
-#include "prismcompat.h"
#include "isl_38xx.h"
#include "islpci_dev.h"
#include "islpci_mgt.h"
diff --git a/drivers/net/wireless/prism54/isl_38xx.h b/drivers/net/wireless/prism54/isl_38xx.h
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 4a20e45..7ed4b00 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -3,6 +3,7 @@
* (C) 2003,2004 Aurelien Alleaume <slts@free.fr>
* (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
* (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
+ * (C) 2006 Christian Lamparter <chunkeey@web.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,18 +27,20 @@ #include <linux/pci.h>
#include <asm/uaccess.h>
-#include "prismcompat.h"
#include "isl_ioctl.h"
#include "islpci_mgt.h"
#include "isl_oid.h" /* additional types and defs for isl38xx fw */
#include "oid_mgt.h"
#include <net/iw_handler.h> /* New driver API */
+#include <net/ieee80211.h>
-#define KEY_SIZE_WEP104 13 /* 104/128-bit WEP keys */
-#define KEY_SIZE_WEP40 5 /* 40/64-bit WEP keys */
+#define KEY_SIZE_WEP40 5 /* 40/64-bit WEP keys */
/* KEY_SIZE_TKIP should match isl_oid.h, struct obj_key.key[] size */
-#define KEY_SIZE_TKIP 32 /* TKIP keys */
+#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
+#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
+
+static u8 wpa_oid[4] = { 0x00, 0x50, 0xf2, 1 };
static void prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid,
u8 *wpa_ie, size_t wpa_ie_len);
@@ -167,14 +170,16 @@ prism54_update_stats(islpci_private *pri
if (down_interruptible(&priv->stats_sem))
return;
-/* Noise floor.
- * I'm not sure if the unit is dBm.
- * Note : If we are not connected, this value seems to be irrelevant. */
+ /* Noise floor.
+ * I'm not sure if the unit is dBm.
+
+ * Note :
+ * If we are not connected, this value seems to be irrelevant. */
mgt_get_request(priv, DOT11_OID_NOISEFLOOR, 0, NULL, &r);
priv->local_iwstatistics.qual.noise = r.u;
-/* Get the rssi of the link. To do this we need to retrieve a bss. */
+ /* Get the rssi of the link. To do this we need to retrieve a bss. */
/* First get the MAC address of the AP we are associated with. */
mgt_get_request(priv, DOT11_OID_BSSID, 0, NULL, &r);
@@ -199,11 +204,11 @@ prism54_update_stats(islpci_private *pri
/* report that the stats are new */
priv->local_iwstatistics.qual.updated = 0x7;
-/* Rx : unable to decrypt the MPDU */
+ /* Rx : unable to decrypt the MPDU */
mgt_get_request(priv, DOT11_OID_PRIVRXFAILED, 0, NULL, &r);
priv->local_iwstatistics.discard.code = r.u;
-/* Tx : Max MAC retries num reached */
+ /* Tx : Max MAC retries num reached */
mgt_get_request(priv, DOT11_OID_MPDUTXFAILED, 0, NULL, &r);
priv->local_iwstatistics.discard.retries = r.u;
@@ -227,7 +232,7 @@ prism54_get_wireless_stats(struct net_de
} 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)) {
@@ -435,11 +440,11 @@ prism54_get_range(struct net_device *nde
/* Now the encoding capabilities */
range->num_encoding_sizes = 3;
/* 64(40) bits WEP */
- range->encoding_size[0] = 5;
+ range->encoding_size[0] = KEY_SIZE_WEP40;
/* 128(104) bits WEP */
- range->encoding_size[1] = 13;
+ range->encoding_size[1] = WEP_KEY_LEN;
/* 256 bits for WPA-PSK */
- range->encoding_size[2] = 32;
+ range->encoding_size[2] = SCM_KEY_LEN;
/* 4 keys are allowed */
range->max_encoding_tokens = 4;
@@ -875,15 +880,6 @@ prism54_set_rate(struct net_device *ndev
data[1] = 0;
}
-/*
- i = 0;
- printk("prism54 rate: ");
- while(data[i]) {
- printk("%u ", data[i]);
- i++;
- }
- printk("0\n");
-*/
profile = -1;
ret = mgt_set_request(priv, DOT11_OID_PROFILES, 0, &profile);
ret |= mgt_set_request(priv, DOT11_OID_EXTENDEDRATES, 0, data);
@@ -1052,18 +1048,58 @@ prism54_get_retry(struct net_device *nde
}
static int
+prism54_set_auth_alg(islpci_private *priv, u32 flag)
+{
+ int authen = DOT11_AUTH_NONE, invoke = 0, exunencrypt = 0;
+ int ret;
+
+ if (flag & IW_ENCODE_RESTRICTED) {
+ authen = DOT11_AUTH_SK;
+ invoke = 1;
+ exunencrypt = 1;
+ }
+
+ if (flag & IW_ENCODE_OPEN) {
+ authen = DOT11_AUTH_OS;
+ invoke = 1;
+ /*
+ This is very wrong here, but we've to ensure bug-to-bug compatibility.
+
+ If we set exunencrypt, the Firmware adds the "Privacy" flag to the
+ Capability Information, which is misreaded by many STA/AP as
+ "the device supports WEP, WPA and WPA2"
+ */
+ exunencrypt = 1;
+ }
+
+ ret =
+ mgt_set_request(priv, DOT11_OID_AUTHENABLE,
+ 0, &authen);
+ ret |=
+ mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED,
+ 0, &invoke);
+ ret |=
+ mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED,
+ 0,&exunencrypt);
+
+ return ret;
+}
+
+static int
prism54_set_encode(struct net_device *ndev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
- int rvalue = 0, force = 0;
- int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0;
+ int rvalue = 0, flags = dwrq->flags;
union oid_res_t r;
/* with the new API, it's impossible to get a NULL pointer.
* New version of iwconfig set the IW_ENCODE_NOKEY flag
* when no key is given, but older versions don't. */
+ if (islpci_get_state(priv) < PRV_STATE_INIT)
+ return -EINVAL;
+
if (dwrq->length > 0) {
/* we have a key to set */
int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
@@ -1071,27 +1107,27 @@ prism54_set_encode(struct net_device *nd
struct obj_key key = { DOT11_PRIV_WEP, 0, "" };
/* get the current key index */
- rvalue = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
+ rvalue |= mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
current_index = r.u;
/* Verify that the key is not marked as invalid */
if (!(dwrq->flags & IW_ENCODE_NOKEY)) {
- if (dwrq->length > KEY_SIZE_TKIP) {
+ if (dwrq->length > MAX_KEY_LEN) {
/* User-provided key data too big */
return -EINVAL;
}
- if (dwrq->length > KEY_SIZE_WEP104) {
+ if (dwrq->length > WEP_KEY_LEN) {
/* WPA-PSK TKIP */
key.type = DOT11_PRIV_TKIP;
- key.length = KEY_SIZE_TKIP;
+ key.length = MAX_KEY_LEN;
} else if (dwrq->length > KEY_SIZE_WEP40) {
/* WEP 104/128 */
- key.length = KEY_SIZE_WEP104;
+ key.length = WEP_KEY_LEN;
} else {
/* WEP 40/64 */
key.length = KEY_SIZE_WEP40;
}
memset(key.key, 0, sizeof (key.key));
- memcpy(key.key, extra, dwrq->length);
+ memcpy(key.key, extra, key.length);
if ((index < 0) || (index > 3))
/* no index provided use the current one */
@@ -1108,95 +1144,111 @@ prism54_set_encode(struct net_device *nd
* This is also how "iwconfig ethX key on" works
*/
if ((index == current_index) && (key.length > 0))
- force = 1;
+ flags |= IW_ENCODE_RESTRICTED;
} else {
- int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
+ int index = (flags & IW_ENCODE_INDEX) - 1;
if ((index >= 0) && (index <= 3)) {
/* we want to set the key index */
rvalue |=
mgt_set_request(priv, DOT11_OID_DEFKEYID, 0,
&index);
} else {
- if (!dwrq->flags & IW_ENCODE_MODE) {
+ if (!(flags & IW_ENCODE_MODE)) {
/* we cannot do anything. Complain. */
return -EINVAL;
}
}
}
- /* now read the flags */
- if (dwrq->flags & IW_ENCODE_DISABLED) {
- /* Encoding disabled,
- * authen = DOT11_AUTH_OS;
- * invoke = 0;
- * exunencrypt = 0; */
- }
- if (dwrq->flags & IW_ENCODE_OPEN)
- /* Encode but accept non-encoded packets. No auth */
- invoke = 1;
- if ((dwrq->flags & IW_ENCODE_RESTRICTED) || force) {
- /* Refuse non-encoded packets. Auth */
- authen = DOT11_AUTH_BOTH;
- invoke = 1;
- exunencrypt = 1;
- }
/* do the change if requested */
- if ((dwrq->flags & IW_ENCODE_MODE) || force) {
- rvalue |=
- mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
- rvalue |=
- mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &invoke);
- rvalue |=
- mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0,
- &exunencrypt);
- }
+ if (flags & IW_ENCODE_MODE)
+ rvalue = prism54_set_auth_alg(priv, flags);
+
return rvalue;
}
static int
+prism54_get_auth_algs(islpci_private *priv)
+{
+ u32 authen = 0, invoke = 0, exunencrypt = 0;
+ union oid_res_t r;
+ int ret = 0;
+
+ ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
+ authen = r.u;
+ ret |= mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
+ invoke = r.u;
+ ret |= mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
+ exunencrypt = r.u;
+
+ if (ret)
+ return ret;
+
+ if (invoke && exunencrypt &&
+ ((authen == DOT11_AUTH_SK) || (authen == DOT11_AUTH_BOTH)))
+ ret = IW_ENCODE_RESTRICTED | IW_ENCODE_ENABLED;
+ else if ((authen == DOT11_AUTH_OS)) {
+ if (invoke)
+ ret = IW_ENCODE_OPEN | IW_ENCODE_ENABLED;
+ else {
+ ret = IW_ENCODE_DISABLED;
+ }
+ }
+ else {
+ ret = IW_ENCODE_DISABLED;
+ }
+
+ return ret;
+}
+
+static int
prism54_get_encode(struct net_device *ndev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
struct obj_key *key;
u32 devindex, index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
- u32 authen = 0, invoke = 0, exunencrypt = 0;
- int rvalue;
+ int rvalue = 0, flags;
union oid_res_t r;
+ if (islpci_get_state(priv) < PRV_STATE_INIT) {
+ dwrq->flags = IW_ENCODE_DISABLED;
+ dwrq->length = 0;
+ return 0;
+ }
+
/* first get the flags */
- rvalue = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
- authen = r.u;
- rvalue |= mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
- invoke = r.u;
- rvalue |= mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
- exunencrypt = r.u;
+ if ((flags = prism54_get_auth_algs(priv)) < 0)
+ return rvalue;
- if (invoke && (authen == DOT11_AUTH_BOTH) && exunencrypt)
- dwrq->flags = IW_ENCODE_RESTRICTED;
- else if ((authen == DOT11_AUTH_OS) && !exunencrypt) {
- if (invoke)
- dwrq->flags = IW_ENCODE_OPEN;
- else
- dwrq->flags = IW_ENCODE_DISABLED;
- } else
- /* The card should not work in this state */
- dwrq->flags = 0;
+ memset(extra, 0x0, dwrq->length);
+ dwrq->flags = flags;
- /* get the current device key index */
- 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))
- /* no index provided, use the current one */
- index = devindex;
- rvalue |= mgt_get_request(priv, DOT11_OID_DEFKEYX, index, NULL, &r);
- key = r.ptr;
- dwrq->length = key->length;
- memcpy(extra, key->key, dwrq->length);
- kfree(key);
- /* return the used key index */
- dwrq->flags |= devindex + 1;
+ if (flags != IW_ENCODE_DISABLED) {
+ /* get the current device key index */
+ 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))
+ /* no index provided, use the current one */
+ index = devindex;
+
+ rvalue |= mgt_get_request(priv, DOT11_OID_DEFKEYX, index, NULL, &r);
+ key = r.ptr;
+
+ if (dwrq->length < key->length) {
+ kfree(key);
+ return -EINVAL;
+ }
+
+ dwrq->length = key->length;
+ memcpy(extra, key->key, dwrq->length);
+ kfree(key);
+ /* return the used key index */
+ dwrq->flags |= devindex + 1;
+ } else
+ rvalue = 0;
+
return rvalue;
}
@@ -1212,7 +1264,7 @@ prism54_get_txpower(struct net_device *n
/* intersil firmware operates in 0.25 dBm (1/4 dBm) */
vwrq->value = (s32) r.u / 4;
vwrq->fixed = 1;
- /* radio is not turned of
+ /* radio is not turned off
* btw: how is possible to turn off only the radio
*/
vwrq->disabled = 0;
@@ -1246,9 +1298,9 @@ prism54_set_txpower(struct net_device *n
}
}
-static int prism54_set_genie(struct net_device *ndev,
- struct iw_request_info *info,
- struct iw_point *data, char *extra)
+static int
+prism54_set_genie(struct net_device *ndev, struct iw_request_info *info,
+ struct iw_point *data, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
int alen, ret = 0;
@@ -1258,6 +1310,9 @@ static int prism54_set_genie(struct net_
(data->length && extra == NULL))
return -EINVAL;
+ if (islpci_get_state(priv) < PRV_STATE_INIT)
+ return -EINVAL;
+
memcpy(priv->wpa_ie, extra, data->length);
priv->wpa_ie_len = data->length;
@@ -1266,28 +1321,25 @@ static int prism54_set_genie(struct net_
if (attach == NULL)
return -ENOMEM;
-#define WLAN_FC_TYPE_MGMT 0
-#define WLAN_FC_STYPE_ASSOC_REQ 0
-#define WLAN_FC_STYPE_REASSOC_REQ 2
-
/* Note: endianness is covered by mgt_set_varlen */
- attach->type = (WLAN_FC_TYPE_MGMT << 2) |
- (WLAN_FC_STYPE_ASSOC_REQ << 4);
- attach->id = -1;
- attach->size = priv->wpa_ie_len;
- memcpy(attach->data, extra, priv->wpa_ie_len);
-
- ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach,
- priv->wpa_ie_len);
- if (ret == 0) {
- attach->type = (WLAN_FC_TYPE_MGMT << 2) |
- (WLAN_FC_STYPE_REASSOC_REQ << 4);
-
- ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach,
- priv->wpa_ie_len);
- if (ret == 0)
- printk(KERN_DEBUG "%s: WPA IE Attachment was set\n",
- ndev->name);
+ attach->id = -1; // global IE
+ attach->size = data->length;
+ memcpy(attach->data, extra, data->length);
+
+ if (priv->iw_mode == IW_MODE_MASTER) {
+ attach->type = DOT11_PKT_BEACON;
+ ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT,
+ attach, data->length);
+ attach->type = DOT11_PKT_PROBE_RESP;
+ ret |= mgt_set_varlen(priv, DOT11_OID_ATTACHMENT,
+ attach, data->length);
+ }
+ else {
+ attach->type = DOT11_PKT_ASSOC_REQ;
+ ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach, data->length);
+ attach->type = DOT11_PKT_REASSOC_REQ;
+ ret |= mgt_set_varlen(priv, DOT11_OID_ATTACHMENT,
+ attach, data->length);
}
kfree(attach);
@@ -1295,9 +1347,9 @@ #define WLAN_FC_STYPE_REASSOC_REQ 2
}
-static int prism54_get_genie(struct net_device *ndev,
- struct iw_request_info *info,
- struct iw_point *data, char *extra)
+static int
+prism54_get_genie(struct net_device *ndev, struct iw_request_info *info,
+ struct iw_point *data, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
int len = priv->wpa_ie_len;
@@ -1316,38 +1368,17 @@ static int prism54_get_genie(struct net_
return 0;
}
-static int prism54_set_auth(struct net_device *ndev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
+static int
+prism54_set_auth(struct net_device *ndev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
struct iw_param *param = &wrqu->param;
- u32 mlmelevel = 0, authen = 0, dot1x = 0;
- u32 exunencrypt = 0, privinvoked = 0, wpa = 0;
- u32 old_wpa;
- int ret = 0;
- union oid_res_t r;
+ u32 set = 0;
+ int rvalue = 0;
if (islpci_get_state(priv) < PRV_STATE_INIT)
- return 0;
-
- /* first get the flags */
- down_write(&priv->mib_sem);
- wpa = old_wpa = priv->wpa;
- up_write(&priv->mib_sem);
- ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
- authen = r.u;
- ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
- privinvoked = r.u;
- ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
- exunencrypt = r.u;
- ret = mgt_get_request(priv, DOT11_OID_DOT1XENABLE, 0, NULL, &r);
- dot1x = r.u;
- ret = mgt_get_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, NULL, &r);
- mlmelevel = r.u;
-
- if (ret < 0)
- goto out;
+ return -EINVAL;
switch (param->flags & IW_AUTH_INDEX) {
case IW_AUTH_CIPHER_PAIRWISE:
@@ -1355,103 +1386,72 @@ static int prism54_set_auth(struct net_d
case IW_AUTH_KEY_MGMT:
break;
- case IW_AUTH_WPA_ENABLED:
- /* Do the same thing as IW_AUTH_WPA_VERSION */
- if (param->value) {
- wpa = 1;
- privinvoked = 1; /* For privacy invoked */
- exunencrypt = 1; /* Filter out all unencrypted frames */
- dot1x = 0x01; /* To enable eap filter */
- mlmelevel = DOT11_MLME_EXTENDED;
- authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
- } else {
- wpa = 0;
- privinvoked = 0;
- exunencrypt = 0; /* Do not filter un-encrypted data */
- dot1x = 0;
- mlmelevel = DOT11_MLME_AUTO;
- }
- break;
-
case IW_AUTH_WPA_VERSION:
- if (param->value & IW_AUTH_WPA_VERSION_DISABLED) {
- wpa = 0;
- privinvoked = 0;
- exunencrypt = 0; /* Do not filter un-encrypted data */
- dot1x = 0;
- mlmelevel = DOT11_MLME_AUTO;
- } else {
- if (param->value & IW_AUTH_WPA_VERSION_WPA)
- wpa = 1;
- else if (param->value & IW_AUTH_WPA_VERSION_WPA2)
- wpa = 2;
- privinvoked = 1; /* For privacy invoked */
- exunencrypt = 1; /* Filter out all unencrypted frames */
- dot1x = 0x01; /* To enable eap filter */
- mlmelevel = DOT11_MLME_EXTENDED;
- authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
- }
+ if (set & IW_AUTH_WPA_VERSION_WPA)
+ set = 1;
+ if (set & IW_AUTH_WPA_VERSION_WPA2)
+ set |= 2;
+ case IW_AUTH_WPA_ENABLED:
+ if (!set)
+ set = param->value ? 3 : 0;
+ rvalue = prism54_set_wpa(ndev, info, &set, extra);
break;
case IW_AUTH_RX_UNENCRYPTED_EAPOL:
- dot1x = param->value ? 1 : 0;
+ set = param->value ? 1 : 0;
+ rvalue = mgt_set_request(priv, DOT11_OID_DOT1XENABLE,
+ 0, &set);
break;
case IW_AUTH_PRIVACY_INVOKED:
- privinvoked = param->value ? 1 : 0;
+ set = param->value ? 1 : 0;
+ rvalue = mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED,
+ 0, &set);
+ break;
case IW_AUTH_DROP_UNENCRYPTED:
- exunencrypt = param->value ? 1 : 0;
+ set = param->value ? 1 : 0;
+ rvalue = mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED,
+ 0, &set);
break;
case IW_AUTH_80211_AUTH_ALG:
- if (param->value & IW_AUTH_ALG_SHARED_KEY) {
- /* Only WEP uses _SK and _BOTH */
- if (wpa > 0) {
- ret = -EINVAL;
- goto out;
- }
- authen = DOT11_AUTH_SK;
- } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
- authen = DOT11_AUTH_OS;
- } else {
- ret = -EINVAL;
- goto out;
+ switch (param->value) {
+ case IW_AUTH_ALG_OPEN_SYSTEM:
+ set = DOT11_AUTH_OS;
+ break;
+ case IW_AUTH_ALG_SHARED_KEY:
+ set = DOT11_AUTH_SK;
+ break;
+ default:
+ return -EINVAL;
+ break;
}
+ rvalue = mgt_set_request(priv, DOT11_OID_AUTHENABLE,
+ 0, &set);
break;
default:
- return -EOPNOTSUPP;
+ rvalue = -EOPNOTSUPP;
+ break;
}
- /* Set all the values */
- down_write(&priv->mib_sem);
- priv->wpa = wpa;
- up_write(&priv->mib_sem);
- mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
- mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &privinvoked);
- mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0, &exunencrypt);
- mgt_set_request(priv, DOT11_OID_DOT1XENABLE, 0, &dot1x);
- mgt_set_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, &mlmelevel);
-
-out:
- return ret;
+ return rvalue;
}
-static int prism54_get_auth(struct net_device *ndev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
+static int
+prism54_get_auth(struct net_device *ndev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
struct iw_param *param = &wrqu->param;
- u32 wpa = 0;
- int ret = 0;
union oid_res_t r;
+ u32 wpa = 0;
+ int rvalue = 0;
if (islpci_get_state(priv) < PRV_STATE_INIT)
return 0;
- /* first get the flags */
down_write(&priv->mib_sem);
wpa = priv->wpa;
up_write(&priv->mib_sem);
@@ -1463,272 +1463,287 @@ static int prism54_get_auth(struct net_d
/*
* wpa_supplicant will control these internally
*/
- ret = -EOPNOTSUPP;
- break;
+ param->value = 0;
+ return -EOPNOTSUPP;
+ break;
case IW_AUTH_WPA_VERSION:
- switch (wpa) {
- case 1:
- param->value = IW_AUTH_WPA_VERSION_WPA;
- break;
- case 2:
- param->value = IW_AUTH_WPA_VERSION_WPA2;
- break;
- case 0:
- default:
+ if (!wpa)
param->value = IW_AUTH_WPA_VERSION_DISABLED;
- break;
- }
+ if (wpa & 1)
+ param->value = IW_AUTH_WPA_VERSION_WPA;
+ if (wpa & 2)
+ param->value |= IW_AUTH_WPA_VERSION_WPA2;
+
break;
case IW_AUTH_DROP_UNENCRYPTED:
- ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
- if (ret >= 0)
- param->value = r.u > 0 ? 1 : 0;
+ rvalue = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED,
+ 0, NULL, &r);
+ param->value = r.u;
break;
case IW_AUTH_80211_AUTH_ALG:
- ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
- if (ret >= 0) {
- switch (r.u) {
- case DOT11_AUTH_OS:
- param->value = IW_AUTH_ALG_OPEN_SYSTEM;
- break;
- case DOT11_AUTH_BOTH:
- case DOT11_AUTH_SK:
- param->value = IW_AUTH_ALG_SHARED_KEY;
- case DOT11_AUTH_NONE:
- default:
- param->value = 0;
- break;
- }
+ rvalue = mgt_get_request(priv, DOT11_OID_AUTHENABLE,
+ 0, NULL, &r);
+
+ switch (r.u) {
+ case DOT11_AUTH_OS:
+ param->value = IW_AUTH_ALG_OPEN_SYSTEM;
+ break;
+ case DOT11_AUTH_BOTH:
+ case DOT11_AUTH_SK:
+ param->value = IW_AUTH_ALG_SHARED_KEY;
+ break;
+ default:
+ param->value = 0;
+ rvalue = -EOPNOTSUPP;
+ break;
}
break;
case IW_AUTH_WPA_ENABLED:
- param->value = wpa > 0 ? 1 : 0;
+ param->value = wpa ? 0 : 1;
break;
case IW_AUTH_RX_UNENCRYPTED_EAPOL:
- ret = mgt_get_request(priv, DOT11_OID_DOT1XENABLE, 0, NULL, &r);
- if (ret >= 0)
- param->value = r.u > 0 ? 1 : 0;
+ rvalue = mgt_get_request(priv, DOT11_OID_DOT1XENABLE,
+ 0, NULL, &r);
+ param->value = r.u;
break;
case IW_AUTH_PRIVACY_INVOKED:
- ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
- if (ret >= 0)
- param->value = r.u > 0 ? 1 : 0;
+ rvalue = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED,
+ 0, NULL, &r);
+ param->value = r.u;
break;
default:
return -EOPNOTSUPP;
+ break;
}
- return ret;
+
+ return 0;
}
-static int prism54_set_encodeext(struct net_device *ndev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+static int
+prism54_set_encodeext(struct net_device *ndev, struct iw_request_info *info,
+ struct iw_point *dwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
- struct iw_point *encoding = &wrqu->encoding;
- struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- int idx, alg = ext->alg, set_key = 1;
+ struct iw_encode_ext *enc = (struct iw_encode_ext *)extra;
+ struct obj_stakey* key;
union oid_res_t r;
- int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0;
- int ret = 0;
+ int index, key_type;
+ int ret = -EINVAL;
- if (islpci_get_state(priv) < PRV_STATE_INIT)
- return 0;
-
- /* Determine and validate the key index */
- idx = (encoding->flags & IW_ENCODE_INDEX) - 1;
- if (idx) {
- if (idx < 0 || idx > 3)
- return -EINVAL;
- } else {
- ret = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
- if (ret < 0)
- goto out;
- idx = r.u;
- }
-
- if (encoding->flags & IW_ENCODE_DISABLED)
- alg = IW_ENCODE_ALG_NONE;
-
- if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
- /* Only set transmit key index here, actual
- * key is set below if needed.
- */
- ret = mgt_set_request(priv, DOT11_OID_DEFKEYID, 0, &idx);
- set_key = ext->key_len > 0 ? 1 : 0;
- }
+ if ((islpci_get_state(priv) < PRV_STATE_INIT) ||
+ (enc->key_len > (dwrq->length - sizeof(*enc))) ||
+ (enc->addr.sa_family != ARPHRD_ETHER))
+ return -EINVAL;
- if (set_key) {
- struct obj_key key = { DOT11_PRIV_WEP, 0, "" };
- switch (alg) {
+ switch (enc->alg) {
case IW_ENCODE_ALG_NONE:
+ return 0;
break;
case IW_ENCODE_ALG_WEP:
- if (ext->key_len > KEY_SIZE_WEP104) {
- ret = -EINVAL;
- goto out;
- }
- if (ext->key_len > KEY_SIZE_WEP40)
- key.length = KEY_SIZE_WEP104;
- else
- key.length = KEY_SIZE_WEP40;
+ key_type = DOT11_PRIV_WEP;
break;
case IW_ENCODE_ALG_TKIP:
- if (ext->key_len > KEY_SIZE_TKIP) {
- ret = -EINVAL;
- goto out;
- }
- key.type = DOT11_PRIV_TKIP;
- key.length = KEY_SIZE_TKIP;
+ key_type = DOT11_PRIV_TKIP;
+ break;
default:
- return -EINVAL;
- }
-
- if (key.length) {
- memset(key.key, 0, sizeof(key.key));
- memcpy(key.key, ext->key, ext->key_len);
- ret = mgt_set_request(priv, DOT11_OID_DEFKEYX, idx,
- &key);
- if (ret < 0)
- goto out;
- }
+ return -EOPNOTSUPP;
}
- /* Read the flags */
- if (encoding->flags & IW_ENCODE_DISABLED) {
- /* Encoding disabled,
- * authen = DOT11_AUTH_OS;
- * invoke = 0;
- * exunencrypt = 0; */
- }
- if (encoding->flags & IW_ENCODE_OPEN) {
- /* Encode but accept non-encoded packets. No auth */
- invoke = 1;
- }
- if (encoding->flags & IW_ENCODE_RESTRICTED) {
- /* Refuse non-encoded packets. Auth */
- authen = DOT11_AUTH_BOTH;
- invoke = 1;
- exunencrypt = 1;
+ index = dwrq->flags & IW_ENCODE_INDEX;
+ if ((index < 0) || (index > 3)) {
+ /* no index provided, so get the current one */
+ ret = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
+ if (ret)
+ return ret;
+ index = r.u;
}
- /* do the change if requested */
- if (encoding->flags & IW_ENCODE_MODE) {
- ret = mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0,
- &authen);
- ret = mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0,
- &invoke);
- ret = mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0,
- &exunencrypt);
+ key = kzalloc(sizeof(*key) + enc->key_len, GFP_KERNEL);
+ if (!key)
+ return -ENOMEM;
+
+ key->type = key_type;
+ key->length = enc->key_len;
+ key->keyid = index;
+ key->reserved = 0;
+ if (!(enc->ext_flags & IW_ENCODE_EXT_GROUP_KEY))
+ key->options = DOT11_STAKEY_OPTION_DEFAULTKEY;
+ else
+ key->options = DOT11_STAKEY_OPTION_GROUPKEY;
+
+ memcpy(key->key, enc->key, key->length);
+ memcpy(key->address, enc->addr.sa_data, ETH_ALEN);
+
+ ret = mgt_set_request(priv, DOT11_OID_STAKEY, 0, key);
+ kfree(key);
+ if (ret)
+ return ret;
+
+ if (enc->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
+ struct obj_stasc *stasc;
+ stasc = kzalloc(sizeof(*stasc), GFP_KERNEL);
+ if (!stasc)
+ return -ENOMEM;
+ memcpy(stasc->address, enc->addr.sa_data, ETH_ALEN);
+ stasc->keyid = index;
+ stasc->tx_sc = 1;
+ memcpy(stasc->sc, enc->rx_seq, 6);
+ ret = mgt_set_request(priv, DOT11_OID_STASC, 0, stasc);
+ kfree(stasc);
+ if (ret)
+ return ret;
}
-out:
+ if (dwrq->flags & IW_ENCODE_MODE)
+ ret = prism54_set_auth_alg(priv, dwrq->flags);
+
return ret;
}
-
-static int prism54_get_encodeext(struct net_device *ndev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+static int
+prism54_get_encodeext(struct net_device *ndev,
+ struct iw_request_info *info, struct iw_point *dwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
- struct iw_point *encoding = &wrqu->encoding;
- struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- int idx, max_key_len;
+ struct iw_encode_ext *enc = (struct iw_encode_ext *)extra;
+ struct obj_stasc *stasc;
union oid_res_t r;
- int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0, wpa = 0;
- int ret = 0;
+ int index;
+ int ret = -EINVAL;
+ int max_key_len;
- if (islpci_get_state(priv) < PRV_STATE_INIT)
- return 0;
-
- /* first get the flags */
- ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
- authen = r.u;
- ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
- invoke = r.u;
- ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
- exunencrypt = r.u;
- if (ret < 0)
- goto out;
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
- max_key_len = encoding->length - sizeof(*ext);
+ max_key_len = dwrq->length - sizeof(*enc);
if (max_key_len < 0)
return -EINVAL;
- idx = (encoding->flags & IW_ENCODE_INDEX) - 1;
- if (idx) {
- if (idx < 0 || idx > 3)
- return -EINVAL;
- } else {
+ memset(enc, 0, sizeof(*enc));
+
+ if (islpci_get_state(priv) < PRV_STATE_INIT) {
+ dwrq->flags = IW_ENCODE_DISABLED;
+ return 0;
+ }
+
+ index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
+ if ((index < 0) || (index > 3)) {
+ /* no index provided, so get the current one */
ret = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
- if (ret < 0)
- goto out;
- idx = r.u;
+ if (ret)
+ return ret;
+ index = r.u;
}
- encoding->flags = idx + 1;
- memset(ext, 0, sizeof(*ext));
+ if (enc->addr.sa_family != ARPHRD_ETHER) {
+ /* no "per-station key" */
+ struct obj_key *key;
+ ret = mgt_get_request(priv, DOT11_OID_DEFKEYX, index, NULL, &r);
+ key = r.ptr;
+ if (ret) {
+ kfree(key);
+ return ret;
+ }
- switch (authen) {
- case DOT11_AUTH_BOTH:
- case DOT11_AUTH_SK:
- wrqu->encoding.flags |= IW_ENCODE_RESTRICTED;
- case DOT11_AUTH_OS:
- default:
- wrqu->encoding.flags |= IW_ENCODE_OPEN;
+ if (key->length > max_key_len) {
+ kfree(key);
+ return -E2BIG;
+ }
+
+ enc->key_len = key->length;
+ switch (key->type) {
+ case DOT11_PRIV_WEP:
+ enc->alg = IW_ENCODE_ALG_WEP;
+ break;
+ case DOT11_PRIV_TKIP:
+ enc->alg = IW_ENCODE_ALG_TKIP;
break;
- }
+ default:
+ kfree(key);
+ return -EIO;
+ break;
+ }
- down_write(&priv->mib_sem);
- wpa = priv->wpa;
- up_write(&priv->mib_sem);
+ dwrq->flags |= IW_ENCODE_ENABLED;
+ memcpy(enc->key, key->key, enc->key_len);
+ dwrq->flags |= index +1;
+ return ret;
- if (authen == DOT11_AUTH_OS && !exunencrypt && !invoke && !wpa) {
- /* No encryption */
- ext->alg = IW_ENCODE_ALG_NONE;
- ext->key_len = 0;
- wrqu->encoding.flags |= IW_ENCODE_DISABLED;
- } else {
- struct obj_key *key;
+ }
+ else {
+ /* no "per-station key" */
+ struct obj_stakey *key;
+ key = kzalloc(sizeof(*key), GFP_KERNEL);
+ if (!key)
+ return -ENOMEM;
+
+ memcpy(key->address, enc->addr.sa_data, ETH_ALEN);
+ key->keyid = index;
+ ret = mgt_get_request(priv, DOT11_OID_STAKEY, 0, (void*)key, &r);
+ kfree(key);
+ key = (struct obj_stakey*)r.ptr;
+ if (ret) {
+ kfree(key);
+ return ret;
+ }
- ret = mgt_get_request(priv, DOT11_OID_DEFKEYX, idx, NULL, &r);
- if (ret < 0)
- goto out;
- key = r.ptr;
- if (max_key_len < key->length) {
- ret = -E2BIG;
- goto out;
+ if (key->length > max_key_len) {
+ kfree(key);
+ return -EINVAL;
}
- memcpy(ext->key, key->key, key->length);
- ext->key_len = key->length;
switch (key->type) {
- case DOT11_PRIV_TKIP:
- ext->alg = IW_ENCODE_ALG_TKIP;
+ case DOT11_PRIV_WEP:
+ enc->alg = IW_ENCODE_ALG_WEP;
break;
- default:
- case DOT11_PRIV_WEP:
- ext->alg = IW_ENCODE_ALG_WEP;
+ case DOT11_PRIV_TKIP:
+ enc->alg = IW_ENCODE_ALG_TKIP;
break;
+ default:
+ kfree(key);
+ return -EIO;
+ break;
+ }
+
+ enc->key_len = key->length;
+ dwrq->flags = index + 1;
+ memcpy(enc->key, key->key, key->length);
+ kfree(key);
+
+ /* add replay counter */
+ stasc = kzalloc(sizeof(*stasc), GFP_KERNEL);
+ if (!stasc)
+ return -ENOMEM;
+
+ memcpy(stasc->address, enc->addr.sa_data, ETH_ALEN);
+ stasc->keyid = index;
+ stasc->tx_sc = 1;
+ ret = mgt_get_request(priv, DOT11_OID_STASC, 0, (void*)stasc, &r);
+ kfree(stasc);
+ stasc = (struct obj_stasc*)r.ptr;
+ if (ret) {
+ kfree(stasc);
+ return ret;
}
- wrqu->encoding.flags |= IW_ENCODE_ENABLED;
+
+ memset(enc->tx_seq, 0, IW_ENCODE_SEQ_MAX_SIZE);
+ // prism's FW has only a 6 byte wide RSC!
+ memcpy(enc->tx_seq, stasc->sc, IW_ENCODE_SEQ_MAX_SIZE - 2);
+ enc->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID;
+ kfree(stasc);
+
}
-out:
return ret;
}
-
static int
prism54_reset(struct net_device *ndev, struct iw_request_info *info,
__u32 * uwrq, char *extra)
@@ -2032,12 +2047,11 @@ format_event(islpci_private *priv, char
{
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 %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X [%2.2x %2.2X %4.4X]",
str,
((priv->iw_mode == IW_MODE_MASTER) ? "from" : "to"),
a[0], a[1], a[2], a[3], a[4], a[5],
- (error ? (mlme->code ? " : REJECTED " : " : ACCEPTED ")
- : ""), mlme->code);
+ mlme->state, mlme->code, mlme->id);
BUG_ON(n > IW_CUSTOM_MAX);
*length = n;
}
@@ -2103,12 +2117,6 @@ struct ieee80211_beacon_phdr {
u16 capab_info;
} __attribute__ ((packed));
-#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)
@@ -2140,10 +2148,9 @@ prism54_wpa_bss_ie_add(islpci_private *p
struct islpci_bss_wpa_ie, list);
list_del(&bss->list);
} else {
- bss = kmalloc(sizeof (*bss), GFP_ATOMIC);
+ bss = kzalloc(sizeof(*bss), GFP_ATOMIC);
if (bss != NULL) {
priv->num_bss_wpa++;
- memset(bss, 0, sizeof (*bss));
}
}
if (bss != NULL) {
@@ -2235,11 +2242,16 @@ prism54_process_bss_data(islpci_private
end = payload + len;
while (pos < end) {
if (pos + 2 + pos[1] > end) {
- printk(KERN_DEBUG "Parsing Beacon/ProbeResp failed "
- "for " MACSTR "\n", MAC2STR(addr));
+ printk(KERN_DEBUG "Parsing %s failed "
+ "for " MACSTR "\n", (oid == DOT11_OID_BEACON ? "Beacon" : "ProbeResp"), MAC2STR(addr));
return;
}
- if (pos[0] == WLAN_EID_GENERIC && pos[1] >= 4 &&
+ /* Don't forget RSN/WPA2 ! */
+ if (pos[0] == MFIE_TYPE_RSN && pos[1] > 4) {
+ prism54_wpa_bss_ie_add(priv, addr, pos, pos[1] + 2);
+ return;
+ }
+ if (pos[0] == MFIE_TYPE_GENERIC && pos[1] >= 4 &&
memcmp(pos + 2, wpa_oid, 4) == 0) {
prism54_wpa_bss_ie_add(priv, addr, pos, pos[1] + 2);
return;
@@ -2264,39 +2276,81 @@ handle_request(islpci_private *priv, str
}
static int
+prism54_process_sta_trap(islpci_private *priv, enum oid_num_t oid,
+ struct obj_mlmeex* mlmeex)
+{
+ struct obj_mlme *mlme = (struct obj_mlme*)mlmeex;
+ int ret = 0;
+
+ switch (oid) {
+ case DOT11_OID_DEAUTHENTICATEEX:
+ send_formatted_event(priv, "DeAuthenticate request",
+ mlme, 0);
+ break;
+
+ case DOT11_OID_AUTHENTICATEEX:
+ if (prism54_mac_accept(&priv->acl, mlmeex->address) &&
+ (mlmeex->state == DOT11_STATE_AUTH)) {
+
+ mlmeex->state = DOT11_STATE_ASSOCING;
+ mlmeex->code = 0;
+ mlmeex->size = 0;
+ ret = mgt_set_request(priv, DOT11_OID_ASSOCIATEEX,
+ 0, mlmeex);
+ if (ret)
+ return ret;
+ }
+ if (mlmeex->code != 0)
+ send_formatted_event(priv, "Authenticate request",
+ mlme, 1);
+ break;
+
+ case DOT11_OID_DISASSOCIATEEX:
+ send_formatted_event(priv, "Disassociate request",
+ mlme, 0);
+ break;
+
+ case DOT11_OID_ASSOCIATEEX:
+ if (mlmeex->code)
+ send_formatted_event(priv, "Associate request",
+ mlme, 1);
+ break;
+
+ case DOT11_OID_REASSOCIATEEX:
+ if (mlmeex->code)
+ send_formatted_event(priv, "Reassociate request",
+ mlme, 1);
+ break;
+
+ default:
+ printk(KERN_INFO "%s: Unhandled OID %x, "
+ "please fill a bug-report!\n", priv->ndev->name, oid);
+ break;
+ }
+
+ return ret;
+}
+
+static int
prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
char *data)
{
struct obj_mlme *mlme = (struct obj_mlme *) data;
struct obj_mlmeex *mlmeex = (struct obj_mlmeex *) data;
- struct obj_mlmeex *confirm;
- u8 wpa_ie[MAX_WPA_IE_LEN];
- int wpa_ie_len;
- size_t len = 0; /* u16, better? */
- u8 *payload = NULL, *pos = NULL;
- int ret;
-
- /* I think all trapable objects are listed here.
- * Some oids have a EX version. The difference is that they are emitted
- * in DOT11_MLME_EXTENDED mode (set with DOT11_OID_MLMEAUTOLEVEL)
- * with more info.
- * The few events already defined by the wireless tools are not really
- * suited. We use the more flexible custom event facility.
- */
-
- if (oid >= DOT11_OID_BEACON) {
- len = mlmeex->size;
- payload = pos = mlmeex->data;
- }
+ int ret = 0;
/* I fear prism54_process_bss_data won't work with big endian data */
- if ((oid == DOT11_OID_BEACON) || (oid == DOT11_OID_PROBE))
- prism54_process_bss_data(priv, oid, mlmeex->address,
- payload, len);
mgt_le_to_cpu(isl_oid[oid].flags & OID_FLAG_TYPE, (void *) mlme);
switch (oid) {
+ case DOT11_OID_BEACON:
+ case DOT11_OID_PROBE:
+ if (priv->iw_mode != IW_MODE_MASTER
+ && mlmeex->state != DOT11_STATE_AUTHING)
+ prism54_process_bss_data(priv, oid, mlmeex->address,
+ mlmeex->data, mlmeex->size);
+ break;
case GEN_OID_LINKSTATE:
link_changed(priv->ndev, (u32) *data);
@@ -2329,163 +2383,12 @@ prism54_process_trap_helper(islpci_priva
send_formatted_event(priv, "ReAssociate request", mlme, 1);
break;
- case DOT11_OID_BEACON:
- send_formatted_event(priv,
- "Received a beacon from an unkown AP",
- mlme, 0);
- break;
-
- case DOT11_OID_PROBE:
- /* we received a probe from a client. */
- send_formatted_event(priv, "Received a probe from client", mlme,
- 0);
- break;
-
- /* Note : "mlme" is actually a "struct obj_mlmeex *" here, but this
- * is backward compatible layout-wise with "struct obj_mlme".
- */
-
- case DOT11_OID_DEAUTHENTICATEEX:
- send_formatted_event(priv, "DeAuthenticate request", mlme, 0);
- break;
-
- case DOT11_OID_AUTHENTICATEEX:
- handle_request(priv, mlme, oid);
- send_formatted_event(priv, "Authenticate request (ex)", mlme, 1);
-
- if (priv->iw_mode != IW_MODE_MASTER
- && mlmeex->state != DOT11_STATE_AUTHING)
- break;
-
- confirm = kmalloc(sizeof(struct obj_mlmeex) + 6, GFP_ATOMIC);
-
- 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]
- );
- confirm->id = -1; /* or mlmeex->id ? */
- confirm->state = 0; /* not used */
- confirm->code = 0;
- confirm->size = 6;
- confirm->data[0] = 0x00;
- confirm->data[1] = 0x00;
- confirm->data[2] = 0x02;
- confirm->data[3] = 0x00;
- confirm->data[4] = 0x00;
- confirm->data[5] = 0x00;
-
- ret = mgt_set_varlen(priv, DOT11_OID_ASSOCIATEEX, confirm, 6);
-
- kfree(confirm);
- if (ret)
- return ret;
- break;
-
- case DOT11_OID_DISASSOCIATEEX:
- send_formatted_event(priv, "Disassociate request (ex)", mlme, 0);
- break;
-
- case DOT11_OID_ASSOCIATEEX:
- handle_request(priv, mlme, oid);
- send_formatted_event(priv, "Associate request (ex)", mlme, 1);
-
- if (priv->iw_mode != IW_MODE_MASTER
- && mlmeex->state != DOT11_STATE_ASSOCING)
- break;
-
- confirm = kmalloc(sizeof(struct obj_mlmeex), GFP_ATOMIC);
-
- if (!confirm)
- break;
-
- memcpy(&confirm->address, mlmeex->address, ETH_ALEN);
-
- confirm->id = ((struct obj_mlmeex *)mlme)->id;
- confirm->state = 0; /* not used */
- confirm->code = 0;
-
- 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]
- );
- kfree(confirm);
- break;
- }
-
- 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;
-
- 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
- && mlmeex->state != DOT11_STATE_ASSOCING)
- break;
-
- confirm = kmalloc(sizeof(struct obj_mlmeex), GFP_ATOMIC);
-
- if (!confirm)
- break;
-
- memcpy(&confirm->address, mlmeex->address, ETH_ALEN);
-
- confirm->id = mlmeex->id;
- confirm->state = 0; /* not used */
- confirm->code = 0;
-
- 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]
- );
- kfree(confirm);
- break;
- }
-
- 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:
- return -EINVAL;
+ ret = prism54_process_sta_trap(priv, oid, mlmeex);
+ break;
}
- return 0;
+ return ret;
}
/*
@@ -2521,368 +2424,33 @@ prism54_set_mac_address(struct net_devic
return ret;
}
-/* Note: currently, use hostapd ioctl from the Host AP driver for WPA
- * support. This is to be replaced with Linux wireless extensions once they
- * get WPA support. */
-
-/* Note II: please leave all this together as it will be easier to remove later,
- * once wireless extensions add WPA support -mcgrof */
-
-/* PRISM54_HOSTAPD ioctl() cmd: */
-enum {
- PRISM2_SET_ENCRYPTION = 6,
- PRISM2_HOSTAPD_SET_GENERIC_ELEMENT = 12,
- PRISM2_HOSTAPD_MLME = 13,
- PRISM2_HOSTAPD_SCAN_REQ = 14,
-};
-
-#define PRISM54_SET_WPA SIOCIWFIRSTPRIV+12
-#define PRISM54_HOSTAPD SIOCIWFIRSTPRIV+25
-#define PRISM54_DROP_UNENCRYPTED SIOCIWFIRSTPRIV+26
-
-#define PRISM2_HOSTAPD_MAX_BUF_SIZE 1024
-#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)
- * used in ioctl() */
-#define HOSTAP_CRYPT_ALG_NAME_LEN 16
-
-struct prism2_hostapd_param {
- u32 cmd;
- u8 sta_addr[ETH_ALEN];
- union {
- struct {
- u8 alg[HOSTAP_CRYPT_ALG_NAME_LEN];
- u32 flags;
- u32 err;
- u8 idx;
- u8 seq[8]; /* sequence counter (set: RX, get: TX) */
- u16 key_len;
- u8 key[0];
- } crypt;
- struct {
- u8 len;
- u8 data[0];
- } generic_elem;
- struct {
-#define MLME_STA_DEAUTH 0
-#define MLME_STA_DISASSOC 1
- u16 cmd;
- u16 reason_code;
- } mlme;
- struct {
- u8 ssid_len;
- u8 ssid[32];
- } scan_req;
- } u;
-};
-
-
-static int
-prism2_ioctl_set_encryption(struct net_device *dev,
- struct prism2_hostapd_param *param,
- int param_len)
-{
- islpci_private *priv = netdev_priv(dev);
- int rvalue = 0, force = 0;
- int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0;
- union oid_res_t r;
-
- /* with the new API, it's impossible to get a NULL pointer.
- * New version of iwconfig set the IW_ENCODE_NOKEY flag
- * when no key is given, but older versions don't. */
-
- if (param->u.crypt.key_len > 0) {
- /* we have a key to set */
- int index = param->u.crypt.idx;
- int current_index;
- struct obj_key key = { DOT11_PRIV_TKIP, 0, "" };
-
- /* get the current key index */
- rvalue = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
- current_index = r.u;
- /* Verify that the key is not marked as invalid */
- if (!(param->u.crypt.flags & IW_ENCODE_NOKEY)) {
- key.length = param->u.crypt.key_len > sizeof (param->u.crypt.key) ?
- sizeof (param->u.crypt.key) : param->u.crypt.key_len;
- memcpy(key.key, param->u.crypt.key, key.length);
- if (key.length == 32)
- /* we want WPA-PSK */
- key.type = DOT11_PRIV_TKIP;
- if ((index < 0) || (index > 3))
- /* no index provided use the current one */
- index = current_index;
-
- /* now send the key to the card */
- rvalue |=
- mgt_set_request(priv, DOT11_OID_DEFKEYX, index,
- &key);
- }
- /*
- * 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
- */
- if ((index == current_index) && (key.length > 0))
- force = 1;
- } else {
- int index = (param->u.crypt.flags & IW_ENCODE_INDEX) - 1;
- if ((index >= 0) && (index <= 3)) {
- /* we want to set the key index */
- rvalue |=
- mgt_set_request(priv, DOT11_OID_DEFKEYID, 0,
- &index);
- } else {
- if (!param->u.crypt.flags & IW_ENCODE_MODE) {
- /* we cannot do anything. Complain. */
- return -EINVAL;
- }
- }
- }
- /* now read the flags */
- if (param->u.crypt.flags & IW_ENCODE_DISABLED) {
- /* Encoding disabled,
- * authen = DOT11_AUTH_OS;
- * invoke = 0;
- * exunencrypt = 0; */
- }
- if (param->u.crypt.flags & IW_ENCODE_OPEN)
- /* Encode but accept non-encoded packets. No auth */
- invoke = 1;
- if ((param->u.crypt.flags & IW_ENCODE_RESTRICTED) || force) {
- /* Refuse non-encoded packets. Auth */
- authen = DOT11_AUTH_BOTH;
- invoke = 1;
- exunencrypt = 1;
- }
- /* do the change if requested */
- if ((param->u.crypt.flags & IW_ENCODE_MODE) || force) {
- rvalue |=
- mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
- rvalue |=
- mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &invoke);
- rvalue |=
- mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0,
- &exunencrypt);
- }
- return rvalue;
-}
-
-static int
-prism2_ioctl_set_generic_element(struct net_device *ndev,
- struct prism2_hostapd_param *param,
- int param_len)
-{
- islpci_private *priv = netdev_priv(ndev);
- int max_len, len, alen, ret=0;
- struct obj_attachment *attach;
-
- len = param->u.generic_elem.len;
- max_len = param_len - PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN;
- if (max_len < 0 || max_len < len)
- return -EINVAL;
-
- alen = sizeof(*attach) + len;
- attach = kmalloc(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
-
- /* Note: endianness is covered by mgt_set_varlen */
-
- attach->type = (WLAN_FC_TYPE_MGMT << 2) |
- (WLAN_FC_STYPE_ASSOC_REQ << 4);
- attach->id = -1;
- attach->size = len;
- memcpy(attach->data, param->u.generic_elem.data, len);
-
- ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach, len);
-
- if (ret == 0) {
- attach->type = (WLAN_FC_TYPE_MGMT << 2) |
- (WLAN_FC_STYPE_REASSOC_REQ << 4);
-
- ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach, len);
-
- if (ret == 0)
- printk(KERN_DEBUG "%s: WPA IE Attachment was set\n",
- ndev->name);
- }
-
- kfree(attach);
- return ret;
-
-}
-
-static int
-prism2_ioctl_mlme(struct net_device *dev, struct prism2_hostapd_param *param)
-{
- return -EOPNOTSUPP;
-}
-
-static int
-prism2_ioctl_scan_req(struct net_device *ndev,
- struct prism2_hostapd_param *param)
-{
- islpci_private *priv = netdev_priv(ndev);
- int i, rvalue;
- struct obj_bsslist *bsslist;
- u32 noise = 0;
- char *extra = "";
- char *current_ev = "foo";
- union oid_res_t r;
-
- if (islpci_get_state(priv) < PRV_STATE_INIT) {
- /* device is not ready, fail gently */
- return 0;
- }
-
- /* first get the noise value. We will use it to report the link quality */
- rvalue = mgt_get_request(priv, DOT11_OID_NOISEFLOOR, 0, NULL, &r);
- noise = r.u;
-
- /* Ask the device for a list of known bss. We can report at most
- * IW_MAX_AP=64 to the range struct. 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 < min(IW_MAX_AP, (int) bsslist->nr); i++)
- current_ev = prism54_translate_bss(ndev, current_ev,
- extra + IW_SCAN_MAX_DATA,
- &(bsslist->bsslist[i]),
- noise);
- kfree(bsslist);
-
- return rvalue;
-}
-
-static int
-prism54_hostapd(struct net_device *ndev, struct iw_point *p)
-{
- struct prism2_hostapd_param *param;
- int ret = 0;
- u32 uwrq;
-
- printk(KERN_DEBUG "prism54_hostapd - len=%d\n", p->length);
- if (p->length < sizeof(struct prism2_hostapd_param) ||
- p->length > PRISM2_HOSTAPD_MAX_BUF_SIZE || !p->pointer)
- return -EINVAL;
-
- param = (struct prism2_hostapd_param *) kmalloc(p->length, GFP_KERNEL);
- if (param == NULL)
- return -ENOMEM;
-
- if (copy_from_user(param, p->pointer, p->length)) {
- kfree(param);
- return -EFAULT;
- }
-
- switch (param->cmd) {
- case PRISM2_SET_ENCRYPTION:
- printk(KERN_DEBUG "%s: Caught WPA supplicant set encryption request\n",
- ndev->name);
- ret = prism2_ioctl_set_encryption(ndev, param, p->length);
- break;
- case PRISM2_HOSTAPD_SET_GENERIC_ELEMENT:
- printk(KERN_DEBUG "%s: Caught WPA supplicant set WPA IE request\n",
- ndev->name);
- ret = prism2_ioctl_set_generic_element(ndev, param,
- p->length);
- break;
- case PRISM2_HOSTAPD_MLME:
- printk(KERN_DEBUG "%s: Caught WPA supplicant MLME request\n",
- ndev->name);
- ret = prism2_ioctl_mlme(ndev, param);
- break;
- case PRISM2_HOSTAPD_SCAN_REQ:
- printk(KERN_DEBUG "%s: Caught WPA supplicant scan request\n",
- ndev->name);
- ret = prism2_ioctl_scan_req(ndev, param);
- break;
- case PRISM54_SET_WPA:
- printk(KERN_DEBUG "%s: Caught WPA supplicant wpa init request\n",
- ndev->name);
- uwrq = 1;
- ret = prism54_set_wpa(ndev, NULL, &uwrq, NULL);
- break;
- case PRISM54_DROP_UNENCRYPTED:
- printk(KERN_DEBUG "%s: Caught WPA drop unencrypted request\n",
- ndev->name);
-#if 0
- uwrq = 0x01;
- mgt_set(priv, DOT11_OID_EXUNENCRYPTED, &uwrq);
- down_write(&priv->mib_sem);
- mgt_commit(priv);
- up_write(&priv->mib_sem);
-#endif
- /* Not necessary, as set_wpa does it, should we just do it here though? */
- ret = 0;
- break;
- default:
- printk(KERN_DEBUG "%s: Caught a WPA supplicant request that is not supported\n",
- ndev->name);
- ret = -EOPNOTSUPP;
- break;
- }
-
- if (ret == 0 && copy_to_user(p->pointer, param, p->length))
- ret = -EFAULT;
-
- kfree(param);
-
- return ret;
-}
-
static int
prism54_set_wpa(struct net_device *ndev, struct iw_request_info *info,
__u32 * uwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
- u32 mlme, authen, dot1x, filter, wep;
+ u32 mlme, dot1x;
if (islpci_get_state(priv) < PRV_STATE_INIT)
return 0;
- wep = 1; /* For privacy invoked */
- filter = 1; /* Filter out all unencrypted frames */
- dot1x = 0x01; /* To enable eap filter */
- mlme = DOT11_MLME_EXTENDED;
- authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
+ dot1x = 0; // disable global filtering
+ mlme = DOT11_MLME_AUTO;
down_write(&priv->mib_sem);
priv->wpa = *uwrq;
- switch (priv->wpa) {
- default:
- case 0: /* Clears/disables WPA and friends */
- wep = 0;
- filter = 0; /* Do not filter un-encrypted data */
- dot1x = 0;
- mlme = DOT11_MLME_AUTO;
- printk("%s: Disabling WPA\n", ndev->name);
- break;
- case 2:
- case 1: /* WPA */
- printk("%s: Enabling WPA\n", ndev->name);
- break;
+ if (priv->wpa) {
+ if (priv->iw_mode == IW_MODE_MASTER)
+ dot1x = 1;
+ mlme = DOT11_MLME_EXTENDED;
}
up_write(&priv->mib_sem);
- mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
- mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &wep);
- mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0, &filter);
mgt_set_request(priv, DOT11_OID_DOT1XENABLE, 0, &dot1x);
mgt_set_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, &mlme);
- return 0;
+ return prism54_set_auth_alg(priv, IW_ENCODE_OPEN);
}
static int
@@ -2890,7 +2458,9 @@ prism54_get_wpa(struct net_device *ndev,
__u32 * uwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
+ down_write(&priv->mib_sem);
*uwrq = priv->wpa;
+ up_write(&priv->mib_sem);
return 0;
}
@@ -3025,6 +2595,80 @@ prism54_set_spy(struct net_device *ndev,
return iw_handler_set_spy(ndev, info, uwrq, extra);
}
+static int
+prism54_send_mlme(struct net_device *ndev, struct iw_request_info *info,
+ struct iw_point *dwrq, char *extra)
+{
+ islpci_private *priv = netdev_priv(ndev);
+ struct iw_mlme *iwmlme;
+ struct obj_mlme mlme;
+ struct obj_sta *sta;
+ union oid_res_t r;
+ int ret = 0;
+
+ if (dwrq->length != sizeof(*iwmlme))
+ return -EINVAL;
+
+ iwmlme = (struct iw_mlme*)extra;
+
+ if (iwmlme->addr.sa_family != ARPHRD_ETHER)
+ return -EINVAL;
+
+ /* get STA/AP Id.
+ or the card will BROADCAST the packet! */
+
+ sta = (struct obj_sta*)kzalloc(sizeof(*sta), GFP_KERNEL);
+ if (!sta)
+ return -ENOMEM;
+
+ memcpy(sta->address, iwmlme->addr.sa_data, ETH_ALEN);
+ ret = mgt_get_request(priv, DOT11_OID_CLIENTFIND, 0, sta, &r);
+ kfree(sta);
+
+ if (ret) {
+ sta = r.ptr;
+ memcpy(mlme.address, iwmlme->addr.sa_data, ETH_ALEN);
+
+ if (sta->node >= 1)
+ mlme.id = sta->node;
+ else
+ mlme.id = -1;
+ } else
+ /* use broadcast id */
+ mlme.id = -1;
+
+ mlme.code = iwmlme->reason_code;
+
+ kfree(r.ptr);
+ switch (iwmlme->cmd) {
+ case IW_MLME_DEAUTH:
+ mlme.state = DOT11_STATE_NONE;
+ return mgt_set_request(priv, DOT11_OID_DEAUTHENTICATE,
+ 0, &mlme);
+ break;
+ case IW_MLME_DISASSOC:
+ mlme.state = DOT11_STATE_NONE;
+ return mgt_set_request(priv, DOT11_OID_DISASSOCIATE,
+ 0, &mlme);
+ break;
+#if 0
+ /* not in WEXT yet */
+ case IW_MLME_AUTH:
+ mlme.state = DOT11_STATE_AUTH;
+ return mgt_set_request(priv, DOT11_OID_AUTHENTICATE,
+ 0, &mlme);
+ break;
+ case IW_MLME_ASSOC:
+ mlme.state = DOT11_STATE_ASSOC;
+ return mgt_set_request(priv, DOT11_OID_ASSOCIATE,
+ 0, &mlme);
+ break;
+#endif
+ }
+
+ return -EOPNOTSUPP;
+}
+
static const iw_handler prism54_handler[] = {
(iw_handler) prism54_commit, /* SIOCSIWCOMMIT */
(iw_handler) prism54_get_name, /* SIOCGIWNAME */
@@ -3042,13 +2686,13 @@ static const iw_handler prism54_handler[
(iw_handler) NULL, /* SIOCGIWPRIV */
(iw_handler) NULL, /* SIOCSIWSTATS */
(iw_handler) NULL, /* SIOCGIWSTATS */
- prism54_set_spy, /* SIOCSIWSPY */
+ (iw_handler) prism54_set_spy, /* SIOCSIWSPY */
iw_handler_get_spy, /* SIOCGIWSPY */
iw_handler_set_thrspy, /* SIOCSIWTHRSPY */
iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
(iw_handler) prism54_set_wap, /* SIOCSIWAP */
(iw_handler) prism54_get_wap, /* SIOCGIWAP */
- (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) prism54_send_mlme, /* SIOCSIWMLME */
(iw_handler) NULL, /* SIOCGIWAPLIST depreciated */
(iw_handler) prism54_set_scan, /* SIOCSIWSCAN */
(iw_handler) prism54_get_scan, /* SIOCGIWSCAN */
@@ -3072,15 +2716,15 @@ static const iw_handler prism54_handler[
(iw_handler) prism54_get_encode, /* SIOCGIWENCODE */
(iw_handler) NULL, /* SIOCSIWPOWER */
(iw_handler) NULL, /* SIOCGIWPOWER */
- NULL, /* -- hole -- */
- NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
(iw_handler) prism54_set_genie, /* SIOCSIWGENIE */
(iw_handler) prism54_get_genie, /* SIOCGIWGENIE */
(iw_handler) prism54_set_auth, /* SIOCSIWAUTH */
(iw_handler) prism54_get_auth, /* SIOCGIWAUTH */
- (iw_handler) prism54_set_encodeext, /* SIOCSIWENCODEEXT */
- (iw_handler) prism54_get_encodeext, /* SIOCGIWENCODEEXT */
- NULL, /* SIOCSIWPMKSA */
+ (iw_handler) prism54_set_encodeext, /* SIOCSIWENCODEEXT */
+ (iw_handler) prism54_get_encodeext, /* SIOCGIWENCODEEXT */
+ (iw_handler) NULL /* SIOCSIWPMKSA */
};
/* The low order bit identify a SET (0) or a GET (1) ioctl. */
@@ -3259,14 +2903,5 @@ const struct iw_handler_def prism54_hand
int
prism54_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
{
- struct iwreq *wrq = (struct iwreq *) rq;
- int ret = -1;
- switch (cmd) {
- case PRISM54_HOSTAPD:
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- ret = prism54_hostapd(ndev, &wrq->u.data);
- return ret;
- }
return -EOPNOTSUPP;
}
diff --git a/drivers/net/wireless/prism54/isl_ioctl.h b/drivers/net/wireless/prism54/isl_ioctl.h
index e8183d3..8322133 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.h
+++ b/drivers/net/wireless/prism54/isl_ioctl.h
@@ -1,4 +1,5 @@
/*
+ *
* Copyright (C) 2002 Intersil Americas Inc.
* (C) 2003 Aurelien Alleaume <slts@free.fr>
* (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
@@ -21,12 +22,11 @@
#ifndef _ISL_IOCTL_H
#define _ISL_IOCTL_H
+#include <net/iw_handler.h> /* New driver API */
#include "islpci_mgt.h"
#include "islpci_dev.h"
-#include <net/iw_handler.h> /* New driver API */
-
-#define SUPPORTED_WIRELESS_EXT 19
+#define SUPPORTED_WIRELESS_EXT 21
void prism54_mib_init(islpci_private *);
diff --git a/drivers/net/wireless/prism54/isl_oid.h b/drivers/net/wireless/prism54/isl_oid.h
index b7534c2..24e727d 100644
--- a/drivers/net/wireless/prism54/isl_oid.h
+++ b/drivers/net/wireless/prism54/isl_oid.h
@@ -2,6 +2,7 @@
* Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
* Copyright (C) 2004 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
* Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
+ * Copyright (C) 2006 Christian Lamparter <chunkeey@web.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,6 +27,8 @@ #define _ISL_OID_H
* with the device firmware
*/
+#define MAX_KEY_LEN 32
+
struct obj_ssid {
u8 length;
char octets[33];
@@ -34,18 +37,28 @@ struct obj_ssid {
struct obj_key {
u8 type; /* dot11_priv_t */
u8 length;
- char key[32];
+ char key[MAX_KEY_LEN];
+} __attribute__ ((packed));
+
+struct obj_stakey {
+ u8 address[ETH_ALEN];
+ u8 keyid;
+ u8 reserved;
+ u16 options; // dot11_stakey_opt_t
+ u8 type; /* dot11_priv_t */
+ u8 length;
+ char key[MAX_KEY_LEN];
} __attribute__ ((packed));
struct obj_mlme {
- u8 address[6];
+ u8 address[ETH_ALEN];
u16 id;
u16 state;
u16 code;
} __attribute__ ((packed));
struct obj_mlmeex {
- u8 address[6];
+ u8 address[ETH_ALEN];
u16 id;
u16 state;
u16 code;
@@ -59,7 +72,7 @@ struct obj_buffer {
} __attribute__ ((packed));
struct obj_bss {
- u8 address[6];
+ u8 address[ETH_ALEN];
int:16; /* padding */
char state;
@@ -97,7 +110,26 @@ struct obj_attachment {
char data[0];
} __attribute__((packed));
-/*
+struct obj_stasc {
+ char address[ETH_ALEN];
+ char keyid;
+ char tx_sc;
+ char sc[6];
+} __attribute__ ((packed));
+
+struct obj_sta {
+ u8 address[ETH_ALEN];
+ int: 16;
+ u8 state;
+ u8 node; // STA ID
+ u16 age;
+ u8 reserved1;
+ u8 rssi;
+ u8 rate;
+ u8 reserved2;
+} __attribute__ ((packed));
+
+/*
* in case everything's ok, the inlined function below will be
* optimized away by the compiler...
*/
@@ -112,6 +144,10 @@ __bug_on_wrong_struct_sizes(void)
BUILD_BUG_ON(sizeof (struct obj_bss) != 60);
BUILD_BUG_ON(sizeof (struct obj_bsslist) != 4);
BUILD_BUG_ON(sizeof (struct obj_frequencies) != 2);
+ BUILD_BUG_ON(sizeof (struct obj_sta) != 16);
+ BUILD_BUG_ON(sizeof (struct obj_stasc) != 14);
+ BUILD_BUG_ON(sizeof (struct obj_stakey) != 44);
+ BUILD_BUG_ON(sizeof (struct obj_attachment) != 6);
}
enum dot11_state_t {
@@ -119,7 +155,7 @@ enum dot11_state_t {
DOT11_STATE_AUTHING = 1,
DOT11_STATE_AUTH = 2,
DOT11_STATE_ASSOCING = 3,
-
+ DOT11_STATE_REASSOC = 4,
DOT11_STATE_ASSOC = 5,
DOT11_STATE_IBSS = 6,
DOT11_STATE_WDS = 7
@@ -464,31 +500,32 @@ enum oid_num_t {
OID_NUM_LAST
};
-#define OID_FLAG_CACHED 0x80
-#define OID_FLAG_TYPE 0x7f
-
-#define OID_TYPE_U32 0x01
-#define OID_TYPE_SSID 0x02
-#define OID_TYPE_KEY 0x03
-#define OID_TYPE_BUFFER 0x04
-#define OID_TYPE_BSS 0x05
-#define OID_TYPE_BSSLIST 0x06
-#define OID_TYPE_FREQUENCIES 0x07
-#define OID_TYPE_MLME 0x08
-#define OID_TYPE_MLMEEX 0x09
-#define OID_TYPE_ADDR 0x0A
-#define OID_TYPE_RAW 0x0B
-#define OID_TYPE_ATTACH 0x0C
-
-/* OID_TYPE_MLMEEX is special because of a variable size field when sending.
- * Not yet implemented (not used in driver anyway).
- */
+enum oid_types_t {
+ OID_TYPE_U32 = 0x01,
+ OID_TYPE_SSID = 0x02,
+ OID_TYPE_KEY = 0x03,
+ OID_TYPE_BUFFER = 0x04,
+ OID_TYPE_BSS = 0x05,
+ OID_TYPE_BSSLIST = 0x06,
+ OID_TYPE_FREQUENCIES = 0x07,
+ OID_TYPE_MLME = 0x08,
+ OID_TYPE_MLMEEX = 0x09,
+ OID_TYPE_ADDR = 0x0A,
+ OID_TYPE_RAW = 0x0B,
+ OID_TYPE_ATTACH = 0x0C,
+ OID_TYPE_STASC = 0x0D,
+ OID_TYPE_STAKEY = 0x0E,
+ OID_TYPE_STAINFO = 0x0F,
+
+ OID_FLAG_CACHED = 0x80,
+ OID_FLAG_TYPE = 0x7f
+};
struct oid_t {
enum oid_num_t oid;
short range; /* to define a range of oid */
short size; /* max size of the associated data */
- char flags;
+ enum oid_types_t flags;
};
union oid_res_t {
@@ -501,5 +538,19 @@ #define IWMAX_BSS 24
#define IWMAX_FREQ 30
#define PRIV_STR_SIZE 1024
+enum dot11_pkt_t {
+ DOT11_PKT_ASSOC_REQ = 0x00,
+ DOT11_PKT_ASSOC_RESP = 0x10,
+ DOT11_PKT_REASSOC_REQ = 0x20,
+ DOT11_PKT_REASSOC_RESP = 0x30,
+ DOT11_PKT_PROBE_RESP = 0x50,
+ DOT11_PKT_BEACON = 0x80
+};
+
+enum dot11_stakey_opt_t {
+ DOT11_STAKEY_OPTION_GROUPKEY = 0x0000,
+ DOT11_STAKEY_OPTION_DEFAULTKEY = 0x0001
+};
+
#endif /* !defined(_ISL_OID_H) */
/* EOF */
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
index 1e0603c..e6d9b26 100644
--- a/drivers/net/wireless/prism54/islpci_dev.c
+++ b/drivers/net/wireless/prism54/islpci_dev.c
@@ -25,10 +25,10 @@ #include <linux/pci.h>
#include <linux/etherdevice.h>
#include <linux/delay.h>
#include <linux/if_arp.h>
+#include <linux/firmware.h>
#include <asm/io.h>
-#include "prismcompat.h"
#include "isl_38xx.h"
#include "isl_ioctl.h"
#include "islpci_dev.h"
@@ -86,7 +86,7 @@ isl_upload_firmware(islpci_private *priv
long fw_len;
const u32 *fw_ptr;
- rc = request_firmware(&fw_entry, priv->firmware, PRISM_FW_PDEV);
+ rc = request_firmware(&fw_entry, priv->firmware, &priv->pdev->dev);
if (rc) {
printk(KERN_ERR
"%s: request_firmware() failed for '%s'\n",
diff --git a/drivers/net/wireless/prism54/islpci_dev.h b/drivers/net/wireless/prism54/islpci_dev.h
index a9aa166..3d0bb8f 100644
--- a/drivers/net/wireless/prism54/islpci_dev.h
+++ b/drivers/net/wireless/prism54/islpci_dev.h
@@ -71,7 +71,6 @@ struct islpci_bss_wpa_ie {
u8 bssid[ETH_ALEN];
u8 wpa_ie[MAX_WPA_IE_LEN];
size_t wpa_ie_len;
-
};
typedef struct {
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
index 676d838..6da1f86 100644
--- a/drivers/net/wireless/prism54/islpci_eth.c
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -24,7 +24,6 @@ #include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
-#include "prismcompat.h"
#include "isl_38xx.h"
#include "islpci_eth.h"
#include "islpci_mgt.h"
@@ -482,8 +481,7 @@ #endif
void
islpci_do_reset_and_wake(void *data)
{
- islpci_private *priv = data;
-
+ islpci_private *priv = (islpci_private *) data;
islpci_reset(priv, 1);
priv->reset_task_pending = 0;
smp_wmb();
@@ -500,13 +498,12 @@ islpci_eth_tx_timeout(struct net_device
statistics->tx_errors++;
if (!priv->reset_task_pending) {
- printk(KERN_WARNING
- "%s: tx_timeout, scheduling reset", ndev->name);
+ printk(KERN_WARNING "%s: tx_timeout\n", ndev->name);
netif_stop_queue(ndev);
priv->reset_task_pending = 1;
schedule_work(&priv->reset_task);
} else {
printk(KERN_WARNING
- "%s: tx_timeout, waiting for reset", ndev->name);
+ "%s: tx_timeout, waiting for reset\n", ndev->name);
}
}
diff --git a/drivers/net/wireless/prism54/islpci_eth.h b/drivers/net/wireless/prism54/islpci_eth.h
diff --git a/drivers/net/wireless/prism54/islpci_hotplug.c b/drivers/net/wireless/prism54/islpci_hotplug.c
index f6354b1..0e07c2b 100644
--- a/drivers/net/wireless/prism54/islpci_hotplug.c
+++ b/drivers/net/wireless/prism54/islpci_hotplug.c
@@ -23,7 +23,6 @@ #include <linux/delay.h>
#include <linux/init.h> /* For __init, __exit */
#include <linux/dma-mapping.h>
-#include "prismcompat.h"
#include "islpci_dev.h"
#include "islpci_mgt.h" /* for pc_debug */
#include "isl_oid.h"
@@ -170,7 +169,8 @@ #endif
pci_set_master(pdev);
/* enable MWI */
- pci_set_mwi(pdev);
+ if (pci_set_mwi(pdev))
+ printk(KERN_ERR "%s: pci_set_mwi failed\n", DRV_NAME);
/* setup the network device interface and its structure */
if (!(ndev = islpci_setup(pdev))) {
@@ -289,7 +289,10 @@ prism54_resume(struct pci_dev *pdev)
islpci_private *priv = ndev ? netdev_priv(ndev) : NULL;
BUG_ON(!priv);
- pci_enable_device(pdev);
+ if (pci_enable_device(pdev)) {
+ printk(KERN_ERR "%s: pci_enable_device() failed.\n", DRV_NAME);
+ return -ENODEV;
+ }
printk(KERN_NOTICE "%s: got resume request\n", ndev->name);
diff --git a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c
index 036a875..8fd781d 100644
--- a/drivers/net/wireless/prism54/islpci_mgt.c
+++ b/drivers/net/wireless/prism54/islpci_mgt.c
@@ -25,7 +25,6 @@ #include <asm/io.h>
#include <asm/system.h>
#include <linux/if_arp.h>
-#include "prismcompat.h"
#include "isl_38xx.h"
#include "islpci_mgt.h"
#include "isl_oid.h" /* additional types and defs for isl38xx fw */
diff --git a/drivers/net/wireless/prism54/islpci_mgt.h b/drivers/net/wireless/prism54/islpci_mgt.h
diff --git a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c
index fbc52b6..24b5a49 100644
--- a/drivers/net/wireless/prism54/oid_mgt.c
+++ b/drivers/net/wireless/prism54/oid_mgt.c
@@ -16,7 +16,6 @@
*
*/
-#include "prismcompat.h"
#include "islpci_dev.h"
#include "islpci_mgt.h"
#include "isl_oid.h"
@@ -85,9 +84,9 @@ struct oid_t isl_oid[] = {
OID_U32_C(DOT11_OID_DEFKEYID, 0x12000003),
[DOT11_OID_DEFKEYX] = {0x12000004, 3, sizeof (struct obj_key),
OID_FLAG_CACHED | OID_TYPE_KEY}, /* DOT11_OID_DEFKEY1,...DOT11_OID_DEFKEY4 */
- OID_UNKNOWN(DOT11_OID_STAKEY, 0x12000008),
+ OID_STRUCT(DOT11_OID_STAKEY, 0x12000008, struct obj_stakey, OID_TYPE_STAKEY),
OID_U32(DOT11_OID_REKEYTHRESHOLD, 0x12000009),
- OID_UNKNOWN(DOT11_OID_STASC, 0x1200000a),
+ OID_STRUCT(DOT11_OID_STASC, 0x1200000a, struct obj_stasc, OID_TYPE_STASC),
OID_U32(DOT11_OID_PRIVTXREJECTED, 0x1a000000),
OID_U32(DOT11_OID_PRIVRXPLAIN, 0x1a000001),
@@ -122,9 +121,10 @@ struct oid_t isl_oid[] = {
OID_U32(DOT11_OID_BRIDGELOCAL, 0x15000000),
OID_U32(DOT11_OID_CLIENTS, 0x15000001),
OID_U32(DOT11_OID_CLIENTSASSOCIATED, 0x15000002),
- [DOT11_OID_CLIENTX] = {0x15000003, 2006, 0, 0}, /* DOT11_OID_CLIENTX,...DOT11_OID_CLIENT2007 */
+ [DOT11_OID_CLIENTX] = {0x15000003, 2006, sizeof(struct obj_sta),
+ OID_TYPE_STAINFO}, /* DOT11_OID_CLIENTX,...DOT11_OID_CLIENT2007 */
- OID_STRUCT(DOT11_OID_CLIENTFIND, 0x150007DB, u8[6], OID_TYPE_ADDR),
+ OID_STRUCT(DOT11_OID_CLIENTFIND, 0x150007DB, struct obj_sta, OID_TYPE_STAINFO),
OID_STRUCT(DOT11_OID_WDSLINKADD, 0x150007DC, u8[6], OID_TYPE_ADDR),
OID_STRUCT(DOT11_OID_WDSLINKREMOVE, 0x150007DD, u8[6], OID_TYPE_ADDR),
OID_STRUCT(DOT11_OID_EAPAUTHSTA, 0x150007DE, u8[6], OID_TYPE_ADDR),
@@ -201,8 +201,7 @@ struct oid_t isl_oid[] = {
OID_U32(DOT11_OID_STATIMEOUT, 0x19000000),
OID_U32_C(DOT11_OID_MLMEAUTOLEVEL, 0x19000001),
OID_U32(DOT11_OID_BSSTIMEOUT, 0x19000002),
- [DOT11_OID_ATTACHMENT] = {0x19000003, 0,
- sizeof(struct obj_attachment), OID_TYPE_ATTACH},
+ OID_STRUCT_C(DOT11_OID_ATTACHMENT, 0x19000003, sizeof(struct obj_attachment), OID_TYPE_ATTACH),
OID_STRUCT_C(DOT11_OID_PSMBUFFER, 0x19000004, struct obj_buffer,
OID_TYPE_BUFFER),
@@ -277,7 +276,7 @@ mgt_clean(islpci_private *priv)
}
void
-mgt_le_to_cpu(int type, void *data)
+mgt_le_to_cpu(enum oid_types_t type, void *data)
{
switch (type) {
case OID_TYPE_U32:
@@ -334,19 +333,31 @@ mgt_le_to_cpu(int type, void *data)
attach->id = le16_to_cpu(attach->id);
attach->size = le16_to_cpu(attach->size);
break;
- }
+ }
+ case OID_TYPE_STAKEY: {
+ struct obj_stakey *stakey = data;
+ stakey->options = le16_to_cpu(stakey->options);
+ break;
+ }
+ case OID_TYPE_STAINFO: {
+ struct obj_sta *sta = data;
+ sta->age = le16_to_cpu(sta->age);
+ break;
+ }
case OID_TYPE_SSID:
case OID_TYPE_KEY:
case OID_TYPE_ADDR:
case OID_TYPE_RAW:
+ case OID_TYPE_STASC:
break;
default:
BUG();
+ break;
}
}
static void
-mgt_cpu_to_le(int type, void *data)
+mgt_cpu_to_le(enum oid_types_t type, void *data)
{
switch (type) {
case OID_TYPE_U32:
@@ -403,14 +414,26 @@ mgt_cpu_to_le(int type, void *data)
attach->id = cpu_to_le16(attach->id);
attach->size = cpu_to_le16(attach->size);
break;
- }
+ }
+ case OID_TYPE_STAKEY: {
+ struct obj_stakey *stakey = data;
+ stakey->options = cpu_to_le16(stakey->options);
+ break;
+ }
+ case OID_TYPE_STAINFO: {
+ struct obj_sta *sta = data;
+ sta->age = cpu_to_le16(sta->age);
+ break;
+ }
case OID_TYPE_SSID:
case OID_TYPE_KEY:
case OID_TYPE_ADDR:
case OID_TYPE_RAW:
+ case OID_TYPE_STASC:
break;
default:
BUG();
+ break;
}
}
@@ -658,13 +681,16 @@ static enum oid_num_t commit_part1[] = {
static enum oid_num_t commit_part2[] = {
DOT11_OID_SSID,
+ /* problematic with WPA
DOT11_OID_PSMBUFFER,
+ */
DOT11_OID_AUTHENABLE,
DOT11_OID_PRIVACYINVOKED,
DOT11_OID_EXUNENCRYPTED,
DOT11_OID_DEFKEYX, /* MULTIPLE */
DOT11_OID_DEFKEYID,
DOT11_OID_DOT1XENABLE,
+ DOT11_OID_ATTACHMENT,
OID_INL_DOT11D_CONFORMANCE,
/* Do not initialize this - fw < 1.0.4.3 rejects it
OID_INL_OUTPUTPOWER,
diff --git a/drivers/net/wireless/prism54/oid_mgt.h b/drivers/net/wireless/prism54/oid_mgt.h
index 92c8a2d..10a5cc3 100644
--- a/drivers/net/wireless/prism54/oid_mgt.h
+++ b/drivers/net/wireless/prism54/oid_mgt.h
@@ -32,7 +32,7 @@ void mgt_clean(islpci_private *);
extern const int frequency_list_a[];
int channel_of_freq(int);
-void mgt_le_to_cpu(int, void *);
+void mgt_le_to_cpu(enum oid_types_t, void *);
int mgt_set_request(islpci_private *, enum oid_num_t, int, void *);
int mgt_set_varlen(islpci_private *, enum oid_num_t, void *, int);
diff --git a/drivers/net/wireless/prism54/prismcompat.h b/drivers/net/wireless/prism54/prismcompat.h
deleted file mode 100644
index aa1d174..0000000
--- a/drivers/net/wireless/prism54/prismcompat.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * (C) 2004 Margit Schubert-While <margitsw@t-online.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/*
- * Compatibility header file to aid support of different kernel versions
- */
-
-#ifdef PRISM54_COMPAT24
-#include "prismcompat24.h"
-#else /* PRISM54_COMPAT24 */
-
-#ifndef _PRISM_COMPAT_H
-#define _PRISM_COMPAT_H
-
-#include <linux/device.h>
-#include <linux/firmware.h>
-#include <linux/moduleparam.h>
-#include <linux/workqueue.h>
-#include <linux/compiler.h>
-
-#ifndef __iomem
-#define __iomem
-#endif
-
-#define PRISM_FW_PDEV &priv->pdev->dev
-
-#endif /* _PRISM_COMPAT_H */
-#endif /* PRISM54_COMPAT24 */
^ permalink raw reply related [flat|nested] 39+ messages in thread
* Re: [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
2006-10-29 12:35 ` [PATCH wireless-2.6-git] prism54: WPA/RSN " chunkeey
@ 2006-10-30 8:50 ` Johannes Berg
2006-10-30 20:17 ` Luis R. Rodriguez
2006-10-30 20:33 ` Dan Williams
2 siblings, 0 replies; 39+ messages in thread
From: Johannes Berg @ 2006-10-30 8:50 UTC (permalink / raw)
To: chunkeey; +Cc: John W. Linville, netdev
On Sun, 2006-10-29 at 14:35 +0200, chunkeey@web.de wrote:
> +#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]:
> +#define MACSTR "%02x: %02x:%02x:%02x:%02x:%02x"
such defines should exist already in ieee80211 headers.
> - /* Update our wireless stats, but do not schedule to often:
> + /* Update our wireless stats, but do not schedule to often :
You could have fixed to->too while at it :)
> - range->encoding_size[0] = 5;:
> + range->encoding_size[0] = KEY_SIZE_WEP40;:
> /* 128(104) bits WEP */
> - range->encoding_size[1] = 13;:
> + range->encoding_size[1] = WEP_KEY_LEN;:
> /* 256 bits for WPA-PSK */
> - range->encoding_size[2] = 32;:
> + range->encoding_size[2] = SCM_KEY_LEN;:
Are there no constants for these in the ieee80211 headers? These look
home-grown.
> + attach->type = DOT11_PKT_BEACON;:
> + attach->type = DOT11_PKT_PROBE_RESP;:
These also look home-grown.
> - "%s %s %2.2X: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X %s (%2.2X)",
> + "%s %s %2.2X: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X [%2.2x %2.2X %4.4X]",
> str,
> ((priv->iw_mode == IW_MODE_MASTER) ? "from" : "to"),
> a[0], a[1], a[2], a[3], a[4], a[5],
Umm...
johannes
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
2006-10-29 12:35 ` [PATCH wireless-2.6-git] prism54: WPA/RSN " chunkeey
2006-10-30 8:50 ` Johannes Berg
@ 2006-10-30 20:17 ` Luis R. Rodriguez
2006-10-31 16:05 ` Dan Williams
2006-10-30 20:33 ` Dan Williams
2 siblings, 1 reply; 39+ messages in thread
From: Luis R. Rodriguez @ 2006-10-30 20:17 UTC (permalink / raw)
To: chunkeey@web.de; +Cc: John W. Linville, netdev
On 10/29/06, chunkeey@web.de <chunkeey@web.de> wrote:
> This patch completes WPA/RSN with TKIP support for all fullmac prism54 cards.
> I removed all parts which are not relevant for wpa_supplicant (managed mode).
This is great effort and thanks for it! My only concern with the patch
is breaking compatiblity with 2.4 but then again I'm tired of having
to keep this compat work up too and soon, after d80211 full force push
it may not be possible. So I ACK it.
Luis
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
2006-10-29 12:35 ` [PATCH wireless-2.6-git] prism54: WPA/RSN " chunkeey
2006-10-30 8:50 ` Johannes Berg
2006-10-30 20:17 ` Luis R. Rodriguez
@ 2006-10-30 20:33 ` Dan Williams
2 siblings, 0 replies; 39+ messages in thread
From: Dan Williams @ 2006-10-30 20:33 UTC (permalink / raw)
To: chunkeey; +Cc: John W. Linville, netdev
On Sun, 2006-10-29 at 14:35 +0200, chunkeey@web.de wrote:
> This patch completes WPA/RSN with TKIP support for all fullmac prism54 cards.
> I removed all parts which are not relevant for wpa_supplicant (managed mode).
>
> you can connect to your WLAN with:
> wpa_supplicant -Dwext -c{WPA_CONF} -i{WPA_ETH}
>
> Signed-off-by: Christian Lamparter <chunkeey@web.de>
>
> off-topic:
> Can someone please check my changelog for spelling "errors"?
What git tree or kernel source version is this patch based off? It
doesn't appear to be based off 2.6.18, 2.6.19-rc3, or wireless-dev. I
wanted to test it out with a WPA access point and see if there are
regressions...
Thanks,
Dan
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
2006-10-30 20:17 ` Luis R. Rodriguez
@ 2006-10-31 16:05 ` Dan Williams
2006-10-31 17:53 ` chunkeey
2006-11-03 14:49 ` Dan Williams
0 siblings, 2 replies; 39+ messages in thread
From: Dan Williams @ 2006-10-31 16:05 UTC (permalink / raw)
To: Luis R. Rodriguez; +Cc: chunkeey@web.de, John W. Linville, netdev
On Mon, 2006-10-30 at 15:17 -0500, Luis R. Rodriguez wrote:
> On 10/29/06, chunkeey@web.de <chunkeey@web.de> wrote:
> > This patch completes WPA/RSN with TKIP support for all fullmac prism54 cards.
> > I removed all parts which are not relevant for wpa_supplicant (managed mode).
>
> This is great effort and thanks for it! My only concern with the patch
> is breaking compatiblity with 2.4 but then again I'm tired of having
> to keep this compat work up too and soon, after d80211 full force push
> it may not be possible. So I ACK it.
I'd like to test it a bit first with my fullmac card before it gets
committed/added... But it's great to get some movement on this
card/driver!
Dan
> Luis
> -
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
2006-10-31 16:05 ` Dan Williams
@ 2006-10-31 17:53 ` chunkeey
2006-11-03 14:49 ` Dan Williams
1 sibling, 0 replies; 39+ messages in thread
From: chunkeey @ 2006-10-31 17:53 UTC (permalink / raw)
To: Dan Williams
[-- Attachment #1: Type: text/plain, Size: 1086 bytes --]
31. Oct 2006 17:05 Dan Williams wrote:
> On Mon, 2006-10-30 at 15:17 -0500, Luis R. Rodriguez wrote:
> > On 10/29/06, chunkeey@web.de <chunkeey@web.de> wrote:
> > > This patch completes WPA/RSN with TKIP support for all fullmac prism54
> > > cards. I removed all parts which are not relevant for wpa_supplicant
> > > (managed mode).
> >
> > This is great effort and thanks for it! My only concern with the patch
> > is breaking compatiblity with 2.4 but then again I'm tired of having
> > to keep this compat work up too and soon, after d80211 full force push
> > it may not be possible. So I ACK it.
>
> I'd like to test it a bit first with my fullmac card before it gets
> committed/added... But it's great to get some movement on this
> card/driver!
>
> Dan
>
Dan, the patch was made for this git-tree:
git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git
BTW, here's a little update:
removes (all) duplicated constants and some "home-grown" definitions
Oh, is there a "#definition" for 40Bit-WEP keys? I only found one for 104Bit
and one for SCM.
Christian
[-- Attachment #2: prism-wpa-wl26git4.patch --]
[-- Type: text/x-diff, Size: 79910 bytes --]
diff --git a/drivers/net/wireless/prism54/isl_38xx.c b/drivers/net/wireless/prism54/isl_38xx.c
index 02fc67b..044a23f 100644
--- a/drivers/net/wireless/prism54/isl_38xx.c
+++ b/drivers/net/wireless/prism54/isl_38xx.c
@@ -24,7 +24,6 @@ #include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/io.h>
-#include "prismcompat.h"
#include "isl_38xx.h"
#include "islpci_dev.h"
#include "islpci_mgt.h"
diff --git a/drivers/net/wireless/prism54/isl_38xx.h b/drivers/net/wireless/prism54/isl_38xx.h
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 4a20e45..126a85e 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -3,6 +3,7 @@
* (C) 2003,2004 Aurelien Alleaume <slts@free.fr>
* (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
* (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
+ * (C) 2006 Christian Lamparter <chunkeey@web.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,18 +27,13 @@ #include <linux/pci.h>
#include <asm/uaccess.h>
-#include "prismcompat.h"
#include "isl_ioctl.h"
#include "islpci_mgt.h"
#include "isl_oid.h" /* additional types and defs for isl38xx fw */
#include "oid_mgt.h"
#include <net/iw_handler.h> /* New driver API */
-
-#define KEY_SIZE_WEP104 13 /* 104/128-bit WEP keys */
-#define KEY_SIZE_WEP40 5 /* 40/64-bit WEP keys */
-/* KEY_SIZE_TKIP should match isl_oid.h, struct obj_key.key[] size */
-#define KEY_SIZE_TKIP 32 /* TKIP keys */
+#include <net/ieee80211.h>
static void prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid,
u8 *wpa_ie, size_t wpa_ie_len);
@@ -45,11 +41,6 @@ static size_t prism54_wpa_bss_ie_get(isl
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
@@ -167,14 +158,16 @@ prism54_update_stats(islpci_private *pri
if (down_interruptible(&priv->stats_sem))
return;
-/* Noise floor.
- * I'm not sure if the unit is dBm.
- * Note : If we are not connected, this value seems to be irrelevant. */
+ /* Noise floor.
+ * I'm not sure if the unit is dBm.
+
+ * Note :
+ * If we are not connected, this value seems to be irrelevant. */
mgt_get_request(priv, DOT11_OID_NOISEFLOOR, 0, NULL, &r);
priv->local_iwstatistics.qual.noise = r.u;
-/* Get the rssi of the link. To do this we need to retrieve a bss. */
+ /* Get the rssi of the link. To do this we need to retrieve a bss. */
/* First get the MAC address of the AP we are associated with. */
mgt_get_request(priv, DOT11_OID_BSSID, 0, NULL, &r);
@@ -199,11 +192,11 @@ prism54_update_stats(islpci_private *pri
/* report that the stats are new */
priv->local_iwstatistics.qual.updated = 0x7;
-/* Rx : unable to decrypt the MPDU */
+ /* Rx : unable to decrypt the MPDU */
mgt_get_request(priv, DOT11_OID_PRIVRXFAILED, 0, NULL, &r);
priv->local_iwstatistics.discard.code = r.u;
-/* Tx : Max MAC retries num reached */
+ /* Tx : Max MAC retries num reached */
mgt_get_request(priv, DOT11_OID_MPDUTXFAILED, 0, NULL, &r);
priv->local_iwstatistics.discard.retries = r.u;
@@ -227,7 +220,7 @@ prism54_get_wireless_stats(struct net_de
} else
priv->iwstatistics.qual.updated = 0;
- /* Update our wireless stats, but do not schedule to often
+ /* Update our wireless stats, but do not schedule too often
* (max 1 HZ) */
if ((priv->stats_timestamp == 0) ||
time_after(jiffies, priv->stats_timestamp + 1 * HZ)) {
@@ -414,6 +407,8 @@ prism54_get_sens(struct net_device *ndev
return rvalue;
}
+#define WEP40_KEY_LEN 5 /* 40/64-bit WEP keys */
+
static int
prism54_get_range(struct net_device *ndev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
@@ -435,11 +430,11 @@ prism54_get_range(struct net_device *nde
/* Now the encoding capabilities */
range->num_encoding_sizes = 3;
/* 64(40) bits WEP */
- range->encoding_size[0] = 5;
+ range->encoding_size[0] = WEP40_KEY_LEN;
/* 128(104) bits WEP */
- range->encoding_size[1] = 13;
+ range->encoding_size[1] = WEP_KEY_LEN;
/* 256 bits for WPA-PSK */
- range->encoding_size[2] = 32;
+ range->encoding_size[2] = SCM_KEY_LEN;
/* 4 keys are allowed */
range->max_encoding_tokens = 4;
@@ -565,6 +560,11 @@ prism54_set_scan(struct net_device *dev,
return 0;
}
+/* In 500 kbps */
+static const unsigned char scan_rate_list[] = { 2, 4, 11, 22,
+ 12, 18, 24, 36,
+ 48, 72, 96, 108 };
+
/* a little helper that will translate our data into a card independent
* format that the Wireless Tools will understand. This was inspired by
* the "Aironet driver for 4500 and 4800 series cards" (GPL)
@@ -596,17 +596,12 @@ prism54_translate_bss(struct net_device
current_ev = iwe_stream_add_point(current_ev, end_buf,
&iwe, bss->ssid.octets);
- /* Capabilities */
-#define CAP_ESS 0x01
-#define CAP_IBSS 0x02
-#define CAP_CRYPT 0x10
-
/* Mode */
cap = bss->capinfo;
iwe.u.mode = 0;
- if (cap & CAP_ESS)
+ if (cap & WLAN_CAPABILITY_ESS)
iwe.u.mode = IW_MODE_MASTER;
- else if (cap & CAP_IBSS)
+ else if (cap & WLAN_CAPABILITY_IBSS)
iwe.u.mode = IW_MODE_ADHOC;
iwe.cmd = SIOCGIWMODE;
if (iwe.u.mode)
@@ -615,7 +610,7 @@ #define CAP_CRYPT 0x10
IW_EV_UINT_LEN);
/* Encryption capability */
- if (cap & CAP_CRYPT)
+ if (cap & WLAN_CAPABILITY_PRIVACY)
iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
@@ -875,15 +870,6 @@ prism54_set_rate(struct net_device *ndev
data[1] = 0;
}
-/*
- i = 0;
- printk("prism54 rate: ");
- while(data[i]) {
- printk("%u ", data[i]);
- i++;
- }
- printk("0\n");
-*/
profile = -1;
ret = mgt_set_request(priv, DOT11_OID_PROFILES, 0, &profile);
ret |= mgt_set_request(priv, DOT11_OID_EXTENDEDRATES, 0, data);
@@ -1052,18 +1038,58 @@ prism54_get_retry(struct net_device *nde
}
static int
+prism54_set_auth_alg(islpci_private *priv, u32 flag)
+{
+ int authen = DOT11_AUTH_NONE, invoke = 0, exunencrypt = 0;
+ int ret;
+
+ if (flag & IW_ENCODE_RESTRICTED) {
+ authen = DOT11_AUTH_SK;
+ invoke = 1;
+ exunencrypt = 1;
+ }
+
+ if (flag & IW_ENCODE_OPEN) {
+ authen = DOT11_AUTH_OS;
+ invoke = 1;
+ /*
+ This is very wrong here, but we've to ensure bug-to-bug compatibility.
+
+ If we set exunencrypt, the Firmware adds the "Privacy" flag to the
+ Capability Information, which is misreaded by many STA/AP as
+ "the device supports WEP, WPA and WPA2"
+ */
+ exunencrypt = 1;
+ }
+
+ ret =
+ mgt_set_request(priv, DOT11_OID_AUTHENABLE,
+ 0, &authen);
+ ret |=
+ mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED,
+ 0, &invoke);
+ ret |=
+ mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED,
+ 0,&exunencrypt);
+
+ return ret;
+}
+
+static int
prism54_set_encode(struct net_device *ndev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
- int rvalue = 0, force = 0;
- int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0;
+ int rvalue = 0, flags = dwrq->flags;
union oid_res_t r;
/* with the new API, it's impossible to get a NULL pointer.
* New version of iwconfig set the IW_ENCODE_NOKEY flag
* when no key is given, but older versions don't. */
+ if (islpci_get_state(priv) < PRV_STATE_INIT)
+ return -EINVAL;
+
if (dwrq->length > 0) {
/* we have a key to set */
int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
@@ -1071,27 +1097,27 @@ prism54_set_encode(struct net_device *nd
struct obj_key key = { DOT11_PRIV_WEP, 0, "" };
/* get the current key index */
- rvalue = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
+ rvalue |= mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
current_index = r.u;
/* Verify that the key is not marked as invalid */
if (!(dwrq->flags & IW_ENCODE_NOKEY)) {
- if (dwrq->length > KEY_SIZE_TKIP) {
+ if (dwrq->length > MAX_KEY_LEN) {
/* User-provided key data too big */
return -EINVAL;
}
- if (dwrq->length > KEY_SIZE_WEP104) {
+ if (dwrq->length > WEP_KEY_LEN) {
/* WPA-PSK TKIP */
key.type = DOT11_PRIV_TKIP;
- key.length = KEY_SIZE_TKIP;
- } else if (dwrq->length > KEY_SIZE_WEP40) {
+ key.length = MAX_KEY_LEN;
+ } else if (dwrq->length > WEP40_KEY_LEN) {
/* WEP 104/128 */
- key.length = KEY_SIZE_WEP104;
+ key.length = WEP_KEY_LEN;
} else {
/* WEP 40/64 */
- key.length = KEY_SIZE_WEP40;
+ key.length = WEP40_KEY_LEN;
}
memset(key.key, 0, sizeof (key.key));
- memcpy(key.key, extra, dwrq->length);
+ memcpy(key.key, extra, key.length);
if ((index < 0) || (index > 3))
/* no index provided use the current one */
@@ -1108,95 +1134,111 @@ prism54_set_encode(struct net_device *nd
* This is also how "iwconfig ethX key on" works
*/
if ((index == current_index) && (key.length > 0))
- force = 1;
+ flags |= IW_ENCODE_RESTRICTED;
} else {
- int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
+ int index = (flags & IW_ENCODE_INDEX) - 1;
if ((index >= 0) && (index <= 3)) {
/* we want to set the key index */
rvalue |=
mgt_set_request(priv, DOT11_OID_DEFKEYID, 0,
&index);
} else {
- if (!dwrq->flags & IW_ENCODE_MODE) {
+ if (!(flags & IW_ENCODE_MODE)) {
/* we cannot do anything. Complain. */
return -EINVAL;
}
}
}
- /* now read the flags */
- if (dwrq->flags & IW_ENCODE_DISABLED) {
- /* Encoding disabled,
- * authen = DOT11_AUTH_OS;
- * invoke = 0;
- * exunencrypt = 0; */
- }
- if (dwrq->flags & IW_ENCODE_OPEN)
- /* Encode but accept non-encoded packets. No auth */
- invoke = 1;
- if ((dwrq->flags & IW_ENCODE_RESTRICTED) || force) {
- /* Refuse non-encoded packets. Auth */
- authen = DOT11_AUTH_BOTH;
- invoke = 1;
- exunencrypt = 1;
- }
/* do the change if requested */
- if ((dwrq->flags & IW_ENCODE_MODE) || force) {
- rvalue |=
- mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
- rvalue |=
- mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &invoke);
- rvalue |=
- mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0,
- &exunencrypt);
- }
+ if (flags & IW_ENCODE_MODE)
+ rvalue = prism54_set_auth_alg(priv, flags);
+
return rvalue;
}
static int
+prism54_get_auth_algs(islpci_private *priv)
+{
+ u32 authen = 0, invoke = 0, exunencrypt = 0;
+ union oid_res_t r;
+ int ret = 0;
+
+ ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
+ authen = r.u;
+ ret |= mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
+ invoke = r.u;
+ ret |= mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
+ exunencrypt = r.u;
+
+ if (ret)
+ return ret;
+
+ if (invoke && exunencrypt &&
+ ((authen == DOT11_AUTH_SK) || (authen == DOT11_AUTH_BOTH)))
+ ret = IW_ENCODE_RESTRICTED | IW_ENCODE_ENABLED;
+ else if ((authen == DOT11_AUTH_OS)) {
+ if (invoke)
+ ret = IW_ENCODE_OPEN | IW_ENCODE_ENABLED;
+ else {
+ ret = IW_ENCODE_DISABLED;
+ }
+ }
+ else {
+ ret = IW_ENCODE_DISABLED;
+ }
+
+ return ret;
+}
+
+static int
prism54_get_encode(struct net_device *ndev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
struct obj_key *key;
u32 devindex, index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
- u32 authen = 0, invoke = 0, exunencrypt = 0;
- int rvalue;
+ int rvalue = 0, flags;
union oid_res_t r;
+ if (islpci_get_state(priv) < PRV_STATE_INIT) {
+ dwrq->flags = IW_ENCODE_DISABLED;
+ dwrq->length = 0;
+ return 0;
+ }
+
/* first get the flags */
- rvalue = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
- authen = r.u;
- rvalue |= mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
- invoke = r.u;
- rvalue |= mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
- exunencrypt = r.u;
+ if ((flags = prism54_get_auth_algs(priv)) < 0)
+ return rvalue;
- if (invoke && (authen == DOT11_AUTH_BOTH) && exunencrypt)
- dwrq->flags = IW_ENCODE_RESTRICTED;
- else if ((authen == DOT11_AUTH_OS) && !exunencrypt) {
- if (invoke)
- dwrq->flags = IW_ENCODE_OPEN;
- else
- dwrq->flags = IW_ENCODE_DISABLED;
- } else
- /* The card should not work in this state */
- dwrq->flags = 0;
+ memset(extra, 0x0, dwrq->length);
+ dwrq->flags = flags;
- /* get the current device key index */
- 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))
- /* no index provided, use the current one */
- index = devindex;
- rvalue |= mgt_get_request(priv, DOT11_OID_DEFKEYX, index, NULL, &r);
- key = r.ptr;
- dwrq->length = key->length;
- memcpy(extra, key->key, dwrq->length);
- kfree(key);
- /* return the used key index */
- dwrq->flags |= devindex + 1;
+ if (flags != IW_ENCODE_DISABLED) {
+ /* get the current device key index */
+ 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))
+ /* no index provided, use the current one */
+ index = devindex;
+
+ rvalue |= mgt_get_request(priv, DOT11_OID_DEFKEYX, index, NULL, &r);
+ key = r.ptr;
+
+ if (dwrq->length < key->length) {
+ kfree(key);
+ return -EINVAL;
+ }
+
+ dwrq->length = key->length;
+ memcpy(extra, key->key, dwrq->length);
+ kfree(key);
+ /* return the used key index */
+ dwrq->flags |= devindex + 1;
+ } else
+ rvalue = 0;
+
return rvalue;
}
@@ -1212,7 +1254,7 @@ prism54_get_txpower(struct net_device *n
/* intersil firmware operates in 0.25 dBm (1/4 dBm) */
vwrq->value = (s32) r.u / 4;
vwrq->fixed = 1;
- /* radio is not turned of
+ /* radio is not turned off
* btw: how is possible to turn off only the radio
*/
vwrq->disabled = 0;
@@ -1246,9 +1288,9 @@ prism54_set_txpower(struct net_device *n
}
}
-static int prism54_set_genie(struct net_device *ndev,
- struct iw_request_info *info,
- struct iw_point *data, char *extra)
+static int
+prism54_set_genie(struct net_device *ndev, struct iw_request_info *info,
+ struct iw_point *data, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
int alen, ret = 0;
@@ -1258,6 +1300,9 @@ static int prism54_set_genie(struct net_
(data->length && extra == NULL))
return -EINVAL;
+ if (islpci_get_state(priv) < PRV_STATE_INIT)
+ return -EINVAL;
+
memcpy(priv->wpa_ie, extra, data->length);
priv->wpa_ie_len = data->length;
@@ -1266,28 +1311,26 @@ static int prism54_set_genie(struct net_
if (attach == NULL)
return -ENOMEM;
-#define WLAN_FC_TYPE_MGMT 0
-#define WLAN_FC_STYPE_ASSOC_REQ 0
-#define WLAN_FC_STYPE_REASSOC_REQ 2
-
/* Note: endianness is covered by mgt_set_varlen */
- attach->type = (WLAN_FC_TYPE_MGMT << 2) |
- (WLAN_FC_STYPE_ASSOC_REQ << 4);
- attach->id = -1;
- attach->size = priv->wpa_ie_len;
- memcpy(attach->data, extra, priv->wpa_ie_len);
-
- ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach,
- priv->wpa_ie_len);
- if (ret == 0) {
- attach->type = (WLAN_FC_TYPE_MGMT << 2) |
- (WLAN_FC_STYPE_REASSOC_REQ << 4);
-
- ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach,
- priv->wpa_ie_len);
- if (ret == 0)
- printk(KERN_DEBUG "%s: WPA IE Attachment was set\n",
- ndev->name);
+ attach->id = -1; // global IE
+ attach->size = data->length;
+ memcpy(attach->data, extra, data->length);
+
+ if (priv->iw_mode == IW_MODE_MASTER) {
+ attach->type = IEEE80211_STYPE_BEACON;
+ ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT,
+ attach, data->length);
+ attach->type = IEEE80211_STYPE_PROBE_RESP;
+ ret |= mgt_set_varlen(priv, DOT11_OID_ATTACHMENT,
+ attach, data->length);
+ }
+ else {
+ attach->type = IEEE80211_STYPE_ASSOC_REQ;
+ ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT,
+ attach, data->length);
+ attach->type = IEEE80211_STYPE_REASSOC_REQ;
+ ret |= mgt_set_varlen(priv, DOT11_OID_ATTACHMENT,
+ attach, data->length);
}
kfree(attach);
@@ -1295,9 +1338,9 @@ #define WLAN_FC_STYPE_REASSOC_REQ 2
}
-static int prism54_get_genie(struct net_device *ndev,
- struct iw_request_info *info,
- struct iw_point *data, char *extra)
+static int
+prism54_get_genie(struct net_device *ndev, struct iw_request_info *info,
+ struct iw_point *data, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
int len = priv->wpa_ie_len;
@@ -1316,38 +1359,17 @@ static int prism54_get_genie(struct net_
return 0;
}
-static int prism54_set_auth(struct net_device *ndev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
+static int
+prism54_set_auth(struct net_device *ndev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
struct iw_param *param = &wrqu->param;
- u32 mlmelevel = 0, authen = 0, dot1x = 0;
- u32 exunencrypt = 0, privinvoked = 0, wpa = 0;
- u32 old_wpa;
- int ret = 0;
- union oid_res_t r;
+ u32 set = 0;
+ int rvalue = 0;
if (islpci_get_state(priv) < PRV_STATE_INIT)
- return 0;
-
- /* first get the flags */
- down_write(&priv->mib_sem);
- wpa = old_wpa = priv->wpa;
- up_write(&priv->mib_sem);
- ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
- authen = r.u;
- ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
- privinvoked = r.u;
- ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
- exunencrypt = r.u;
- ret = mgt_get_request(priv, DOT11_OID_DOT1XENABLE, 0, NULL, &r);
- dot1x = r.u;
- ret = mgt_get_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, NULL, &r);
- mlmelevel = r.u;
-
- if (ret < 0)
- goto out;
+ return -EINVAL;
switch (param->flags & IW_AUTH_INDEX) {
case IW_AUTH_CIPHER_PAIRWISE:
@@ -1355,103 +1377,72 @@ static int prism54_set_auth(struct net_d
case IW_AUTH_KEY_MGMT:
break;
- case IW_AUTH_WPA_ENABLED:
- /* Do the same thing as IW_AUTH_WPA_VERSION */
- if (param->value) {
- wpa = 1;
- privinvoked = 1; /* For privacy invoked */
- exunencrypt = 1; /* Filter out all unencrypted frames */
- dot1x = 0x01; /* To enable eap filter */
- mlmelevel = DOT11_MLME_EXTENDED;
- authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
- } else {
- wpa = 0;
- privinvoked = 0;
- exunencrypt = 0; /* Do not filter un-encrypted data */
- dot1x = 0;
- mlmelevel = DOT11_MLME_AUTO;
- }
- break;
-
case IW_AUTH_WPA_VERSION:
- if (param->value & IW_AUTH_WPA_VERSION_DISABLED) {
- wpa = 0;
- privinvoked = 0;
- exunencrypt = 0; /* Do not filter un-encrypted data */
- dot1x = 0;
- mlmelevel = DOT11_MLME_AUTO;
- } else {
- if (param->value & IW_AUTH_WPA_VERSION_WPA)
- wpa = 1;
- else if (param->value & IW_AUTH_WPA_VERSION_WPA2)
- wpa = 2;
- privinvoked = 1; /* For privacy invoked */
- exunencrypt = 1; /* Filter out all unencrypted frames */
- dot1x = 0x01; /* To enable eap filter */
- mlmelevel = DOT11_MLME_EXTENDED;
- authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
- }
+ if (set & IW_AUTH_WPA_VERSION_WPA)
+ set = 1;
+ if (set & IW_AUTH_WPA_VERSION_WPA2)
+ set |= 2;
+ case IW_AUTH_WPA_ENABLED:
+ if (!set)
+ set = param->value ? 3 : 0;
+ rvalue = prism54_set_wpa(ndev, info, &set, extra);
break;
case IW_AUTH_RX_UNENCRYPTED_EAPOL:
- dot1x = param->value ? 1 : 0;
+ set = param->value ? 1 : 0;
+ rvalue = mgt_set_request(priv, DOT11_OID_DOT1XENABLE,
+ 0, &set);
break;
case IW_AUTH_PRIVACY_INVOKED:
- privinvoked = param->value ? 1 : 0;
+ set = param->value ? 1 : 0;
+ rvalue = mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED,
+ 0, &set);
+ break;
case IW_AUTH_DROP_UNENCRYPTED:
- exunencrypt = param->value ? 1 : 0;
+ set = param->value ? 1 : 0;
+ rvalue = mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED,
+ 0, &set);
break;
case IW_AUTH_80211_AUTH_ALG:
- if (param->value & IW_AUTH_ALG_SHARED_KEY) {
- /* Only WEP uses _SK and _BOTH */
- if (wpa > 0) {
- ret = -EINVAL;
- goto out;
- }
- authen = DOT11_AUTH_SK;
- } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
- authen = DOT11_AUTH_OS;
- } else {
- ret = -EINVAL;
- goto out;
+ switch (param->value) {
+ case IW_AUTH_ALG_OPEN_SYSTEM:
+ set = DOT11_AUTH_OS;
+ break;
+ case IW_AUTH_ALG_SHARED_KEY:
+ set = DOT11_AUTH_SK;
+ break;
+ default:
+ return -EINVAL;
+ break;
}
+ rvalue = mgt_set_request(priv, DOT11_OID_AUTHENABLE,
+ 0, &set);
break;
default:
- return -EOPNOTSUPP;
+ rvalue = -EOPNOTSUPP;
+ break;
}
- /* Set all the values */
- down_write(&priv->mib_sem);
- priv->wpa = wpa;
- up_write(&priv->mib_sem);
- mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
- mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &privinvoked);
- mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0, &exunencrypt);
- mgt_set_request(priv, DOT11_OID_DOT1XENABLE, 0, &dot1x);
- mgt_set_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, &mlmelevel);
-
-out:
- return ret;
+ return rvalue;
}
-static int prism54_get_auth(struct net_device *ndev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
+static int
+prism54_get_auth(struct net_device *ndev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
struct iw_param *param = &wrqu->param;
- u32 wpa = 0;
- int ret = 0;
union oid_res_t r;
+ u32 wpa = 0;
+ int rvalue = 0;
if (islpci_get_state(priv) < PRV_STATE_INIT)
return 0;
- /* first get the flags */
down_write(&priv->mib_sem);
wpa = priv->wpa;
up_write(&priv->mib_sem);
@@ -1463,272 +1454,292 @@ static int prism54_get_auth(struct net_d
/*
* wpa_supplicant will control these internally
*/
- ret = -EOPNOTSUPP;
- break;
+ param->value = 0;
+ return -EOPNOTSUPP;
+ break;
case IW_AUTH_WPA_VERSION:
- switch (wpa) {
- case 1:
- param->value = IW_AUTH_WPA_VERSION_WPA;
- break;
- case 2:
- param->value = IW_AUTH_WPA_VERSION_WPA2;
- break;
- case 0:
- default:
+ if (!wpa)
param->value = IW_AUTH_WPA_VERSION_DISABLED;
- break;
- }
+ if (wpa & 1)
+ param->value = IW_AUTH_WPA_VERSION_WPA;
+ if (wpa & 2)
+ param->value |= IW_AUTH_WPA_VERSION_WPA2;
+
break;
case IW_AUTH_DROP_UNENCRYPTED:
- ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
- if (ret >= 0)
- param->value = r.u > 0 ? 1 : 0;
+ rvalue = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED,
+ 0, NULL, &r);
+ param->value = r.u;
break;
case IW_AUTH_80211_AUTH_ALG:
- ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
- if (ret >= 0) {
- switch (r.u) {
- case DOT11_AUTH_OS:
- param->value = IW_AUTH_ALG_OPEN_SYSTEM;
- break;
- case DOT11_AUTH_BOTH:
- case DOT11_AUTH_SK:
- param->value = IW_AUTH_ALG_SHARED_KEY;
- case DOT11_AUTH_NONE:
- default:
- param->value = 0;
- break;
- }
+ rvalue = mgt_get_request(priv, DOT11_OID_AUTHENABLE,
+ 0, NULL, &r);
+
+ switch (r.u) {
+ case DOT11_AUTH_OS:
+ param->value = IW_AUTH_ALG_OPEN_SYSTEM;
+ break;
+ case DOT11_AUTH_BOTH:
+ case DOT11_AUTH_SK:
+ param->value = IW_AUTH_ALG_SHARED_KEY;
+ break;
+ default:
+ param->value = 0;
+ rvalue = -EOPNOTSUPP;
+ break;
}
break;
case IW_AUTH_WPA_ENABLED:
- param->value = wpa > 0 ? 1 : 0;
+ param->value = wpa ? 0 : 1;
break;
case IW_AUTH_RX_UNENCRYPTED_EAPOL:
- ret = mgt_get_request(priv, DOT11_OID_DOT1XENABLE, 0, NULL, &r);
- if (ret >= 0)
- param->value = r.u > 0 ? 1 : 0;
+ rvalue = mgt_get_request(priv, DOT11_OID_DOT1XENABLE,
+ 0, NULL, &r);
+ param->value = r.u;
break;
case IW_AUTH_PRIVACY_INVOKED:
- ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
- if (ret >= 0)
- param->value = r.u > 0 ? 1 : 0;
+ rvalue = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED,
+ 0, NULL, &r);
+ param->value = r.u;
break;
default:
return -EOPNOTSUPP;
+ break;
}
- return ret;
+
+ return 0;
}
-static int prism54_set_encodeext(struct net_device *ndev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+static int
+prism54_set_encodeext(struct net_device *ndev, struct iw_request_info *info,
+ struct iw_point *dwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
- struct iw_point *encoding = &wrqu->encoding;
- struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- int idx, alg = ext->alg, set_key = 1;
+ struct iw_encode_ext *enc = (struct iw_encode_ext *)extra;
+ struct obj_stakey* key;
union oid_res_t r;
- int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0;
- int ret = 0;
-
- if (islpci_get_state(priv) < PRV_STATE_INIT)
- return 0;
-
- /* Determine and validate the key index */
- idx = (encoding->flags & IW_ENCODE_INDEX) - 1;
- if (idx) {
- if (idx < 0 || idx > 3)
- return -EINVAL;
- } else {
- ret = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
- if (ret < 0)
- goto out;
- idx = r.u;
- }
+ int index, key_type, keyop = DOT11_KEYOP_SET_KEY;
+ int ret = -EINVAL;
- if (encoding->flags & IW_ENCODE_DISABLED)
- alg = IW_ENCODE_ALG_NONE;
-
- if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
- /* Only set transmit key index here, actual
- * key is set below if needed.
- */
- ret = mgt_set_request(priv, DOT11_OID_DEFKEYID, 0, &idx);
- set_key = ext->key_len > 0 ? 1 : 0;
- }
+ if ((islpci_get_state(priv) < PRV_STATE_INIT) ||
+ (enc->key_len > (dwrq->length - sizeof(*enc))) ||
+ (enc->addr.sa_family != ARPHRD_ETHER))
+ return -EINVAL;
- if (set_key) {
- struct obj_key key = { DOT11_PRIV_WEP, 0, "" };
- switch (alg) {
+ switch (enc->alg) {
case IW_ENCODE_ALG_NONE:
+#if 0
+ key_type = DOT11_PRIV_WEP;
+ keyop = DOT11_KEYOP_REMOVE_KEY;
+#else
+ return 0;
+#endif
break;
case IW_ENCODE_ALG_WEP:
- if (ext->key_len > KEY_SIZE_WEP104) {
- ret = -EINVAL;
- goto out;
- }
- if (ext->key_len > KEY_SIZE_WEP40)
- key.length = KEY_SIZE_WEP104;
- else
- key.length = KEY_SIZE_WEP40;
+ key_type = DOT11_PRIV_WEP;
break;
case IW_ENCODE_ALG_TKIP:
- if (ext->key_len > KEY_SIZE_TKIP) {
- ret = -EINVAL;
- goto out;
- }
- key.type = DOT11_PRIV_TKIP;
- key.length = KEY_SIZE_TKIP;
+ key_type = DOT11_PRIV_TKIP;
+ break;
default:
- return -EINVAL;
- }
-
- if (key.length) {
- memset(key.key, 0, sizeof(key.key));
- memcpy(key.key, ext->key, ext->key_len);
- ret = mgt_set_request(priv, DOT11_OID_DEFKEYX, idx,
- &key);
- if (ret < 0)
- goto out;
- }
+ return -EOPNOTSUPP;
}
- /* Read the flags */
- if (encoding->flags & IW_ENCODE_DISABLED) {
- /* Encoding disabled,
- * authen = DOT11_AUTH_OS;
- * invoke = 0;
- * exunencrypt = 0; */
- }
- if (encoding->flags & IW_ENCODE_OPEN) {
- /* Encode but accept non-encoded packets. No auth */
- invoke = 1;
- }
- if (encoding->flags & IW_ENCODE_RESTRICTED) {
- /* Refuse non-encoded packets. Auth */
- authen = DOT11_AUTH_BOTH;
- invoke = 1;
- exunencrypt = 1;
+ index = (dwrq->flags & IW_ENCODE_INDEX);
+ if ((index < 0) || (index > 3)) {
+ /* no index provided, so get the current one */
+ ret = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
+ if (ret)
+ return ret;
+ index = r.u;
}
- /* do the change if requested */
- if (encoding->flags & IW_ENCODE_MODE) {
- ret = mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0,
- &authen);
- ret = mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0,
- &invoke);
- ret = mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0,
- &exunencrypt);
+ key = kzalloc(sizeof(*key) + enc->key_len, GFP_KERNEL);
+ if (!key)
+ return -ENOMEM;
+
+ key->type = key_type;
+ key->length = enc->key_len;
+ key->keyid = index;
+ key->reserved = keyop;
+ if (!(enc->ext_flags & IW_ENCODE_EXT_GROUP_KEY))
+ key->options = DOT11_STAKEY_OPTION_DEFAULTKEY;
+ else
+ key->options = DOT11_STAKEY_OPTION_GROUPKEY;
+
+ memcpy(key->key, enc->key, key->length);
+ memcpy(key->address, enc->addr.sa_data, ETH_ALEN);
+
+ ret = mgt_set_request(priv, DOT11_OID_STAKEY, 0, key);
+ kfree(key);
+ if (ret)
+ return ret;
+
+ if (enc->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
+ struct obj_stasc *stasc;
+ stasc = kzalloc(sizeof(*stasc), GFP_KERNEL);
+ if (!stasc)
+ return -ENOMEM;
+ memcpy(stasc->address, enc->addr.sa_data, ETH_ALEN);
+ stasc->keyid = index;
+ stasc->tx_sc = 1;
+ memcpy(stasc->sc, enc->rx_seq, 6);
+ ret = mgt_set_request(priv, DOT11_OID_STASC, 0, stasc);
+ kfree(stasc);
+ if (ret)
+ return ret;
}
-out:
+ if (dwrq->flags & IW_ENCODE_MODE)
+ ret = prism54_set_auth_alg(priv, dwrq->flags);
+
return ret;
}
-
-static int prism54_get_encodeext(struct net_device *ndev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+static int
+prism54_get_encodeext(struct net_device *ndev,
+ struct iw_request_info *info, struct iw_point *dwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
- struct iw_point *encoding = &wrqu->encoding;
- struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- int idx, max_key_len;
+ struct iw_encode_ext *enc = (struct iw_encode_ext *)extra;
+ struct obj_stasc *stasc;
union oid_res_t r;
- int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0, wpa = 0;
- int ret = 0;
+ int index;
+ int ret = -EINVAL;
+ int max_key_len;
- if (islpci_get_state(priv) < PRV_STATE_INIT)
- return 0;
-
- /* first get the flags */
- ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
- authen = r.u;
- ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
- invoke = r.u;
- ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
- exunencrypt = r.u;
- if (ret < 0)
- goto out;
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
- max_key_len = encoding->length - sizeof(*ext);
+ max_key_len = dwrq->length - sizeof(*enc);
if (max_key_len < 0)
return -EINVAL;
- idx = (encoding->flags & IW_ENCODE_INDEX) - 1;
- if (idx) {
- if (idx < 0 || idx > 3)
- return -EINVAL;
- } else {
+ memset(enc, 0, sizeof(*enc));
+
+ if (islpci_get_state(priv) < PRV_STATE_INIT) {
+ dwrq->flags = IW_ENCODE_DISABLED;
+ return 0;
+ }
+
+ index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
+ if ((index < 0) || (index > 3)) {
+ /* no index provided, so get the current one */
ret = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
- if (ret < 0)
- goto out;
- idx = r.u;
+ if (ret)
+ return ret;
+ index = r.u;
}
- encoding->flags = idx + 1;
- memset(ext, 0, sizeof(*ext));
+ if (enc->addr.sa_family != ARPHRD_ETHER) {
+ /* no "per-station key" */
+ struct obj_key *key;
+ ret = mgt_get_request(priv, DOT11_OID_DEFKEYX, index, NULL, &r);
+ key = r.ptr;
+ if (ret) {
+ kfree(key);
+ return ret;
+ }
- switch (authen) {
- case DOT11_AUTH_BOTH:
- case DOT11_AUTH_SK:
- wrqu->encoding.flags |= IW_ENCODE_RESTRICTED;
- case DOT11_AUTH_OS:
- default:
- wrqu->encoding.flags |= IW_ENCODE_OPEN;
+ if (key->length > max_key_len) {
+ kfree(key);
+ return -E2BIG;
+ }
+
+ enc->key_len = key->length;
+ switch (key->type) {
+ case DOT11_PRIV_WEP:
+ enc->alg = IW_ENCODE_ALG_WEP;
+ break;
+ case DOT11_PRIV_TKIP:
+ enc->alg = IW_ENCODE_ALG_TKIP;
break;
- }
+ default:
+ kfree(key);
+ return -EIO;
+ break;
+ }
- down_write(&priv->mib_sem);
- wpa = priv->wpa;
- up_write(&priv->mib_sem);
+ dwrq->flags |= IW_ENCODE_ENABLED;
+ memcpy(enc->key, key->key, enc->key_len);
+ dwrq->flags |= index +1;
+ return ret;
- if (authen == DOT11_AUTH_OS && !exunencrypt && !invoke && !wpa) {
- /* No encryption */
- ext->alg = IW_ENCODE_ALG_NONE;
- ext->key_len = 0;
- wrqu->encoding.flags |= IW_ENCODE_DISABLED;
- } else {
- struct obj_key *key;
+ }
+ else {
+ /* no "per-station key" */
+ struct obj_stakey *key;
+ key = kzalloc(sizeof(*key), GFP_KERNEL);
+ if (!key)
+ return -ENOMEM;
+
+ memcpy(key->address, enc->addr.sa_data, ETH_ALEN);
+ key->keyid = index;
+ ret = mgt_get_request(priv, DOT11_OID_STAKEY, 0, (void*)key, &r);
+ kfree(key);
+ key = (struct obj_stakey*)r.ptr;
+ if (ret) {
+ kfree(key);
+ return ret;
+ }
- ret = mgt_get_request(priv, DOT11_OID_DEFKEYX, idx, NULL, &r);
- if (ret < 0)
- goto out;
- key = r.ptr;
- if (max_key_len < key->length) {
- ret = -E2BIG;
- goto out;
+ if (key->length > max_key_len) {
+ kfree(key);
+ return -EINVAL;
}
- memcpy(ext->key, key->key, key->length);
- ext->key_len = key->length;
switch (key->type) {
- case DOT11_PRIV_TKIP:
- ext->alg = IW_ENCODE_ALG_TKIP;
+ case DOT11_PRIV_WEP:
+ enc->alg = IW_ENCODE_ALG_WEP;
break;
- default:
- case DOT11_PRIV_WEP:
- ext->alg = IW_ENCODE_ALG_WEP;
+ case DOT11_PRIV_TKIP:
+ enc->alg = IW_ENCODE_ALG_TKIP;
+ break;
+ default:
+ kfree(key);
+ return -EIO;
break;
}
- wrqu->encoding.flags |= IW_ENCODE_ENABLED;
+
+ enc->key_len = key->length;
+ dwrq->flags = index + 1;
+ memcpy(enc->key, key->key, key->length);
+ kfree(key);
+
+ /* add replay counter */
+ stasc = kzalloc(sizeof(*stasc), GFP_KERNEL);
+ if (!stasc)
+ return -ENOMEM;
+
+ memcpy(stasc->address, enc->addr.sa_data, ETH_ALEN);
+ stasc->keyid = index;
+ stasc->tx_sc = 1;
+ ret = mgt_get_request(priv, DOT11_OID_STASC, 0, (void*)stasc, &r);
+ kfree(stasc);
+ stasc = (struct obj_stasc*)r.ptr;
+ if (ret) {
+ kfree(stasc);
+ return ret;
+ }
+
+ memset(enc->tx_seq, 0, IW_ENCODE_SEQ_MAX_SIZE);
+ // prism's FW has only a 6 byte wide RSC!
+ memcpy(enc->tx_seq, stasc->sc, IW_ENCODE_SEQ_MAX_SIZE - 2);
+ enc->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID;
+ kfree(stasc);
+
}
-out:
return ret;
}
-
static int
prism54_reset(struct net_device *ndev, struct iw_request_info *info,
__u32 * uwrq, char *extra)
@@ -2030,14 +2041,12 @@ 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 " MAC_FMT " [%2.2x %2.2X %4.4X]",
str,
((priv->iw_mode == IW_MODE_MASTER) ? "from" : "to"),
- a[0], a[1], a[2], a[3], a[4], a[5],
- (error ? (mlme->code ? " : REJECTED " : " : ACCEPTED ")
- : ""), mlme->code);
+ MAC_ARG(mlme->address),
+ mlme->state, mlme->code, mlme->id);
BUG_ON(n > IW_CUSTOM_MAX);
*length = n;
}
@@ -2103,12 +2112,6 @@ struct ieee80211_beacon_phdr {
u16 capab_info;
} __attribute__ ((packed));
-#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)
@@ -2140,10 +2143,9 @@ prism54_wpa_bss_ie_add(islpci_private *p
struct islpci_bss_wpa_ie, list);
list_del(&bss->list);
} else {
- bss = kmalloc(sizeof (*bss), GFP_ATOMIC);
+ bss = kzalloc(sizeof(*bss), GFP_ATOMIC);
if (bss != NULL) {
priv->num_bss_wpa++;
- memset(bss, 0, sizeof (*bss));
}
}
if (bss != NULL) {
@@ -2157,8 +2159,8 @@ prism54_wpa_bss_ie_add(islpci_private *p
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 " MAC_FMT
+ "\n", MAC_ARG(bssid));
}
/* expire old entries from WPA list */
@@ -2220,6 +2222,8 @@ prism54_wpa_bss_ie_clean(islpci_private
}
}
+static u8 wpa_oid[4] = { 0x00, 0x50, 0xf2, 1 };
+
static void
prism54_process_bss_data(islpci_private *priv, u32 oid, u8 *addr,
u8 *payload, size_t len)
@@ -2235,11 +2239,16 @@ prism54_process_bss_data(islpci_private
end = payload + len;
while (pos < end) {
if (pos + 2 + pos[1] > end) {
- printk(KERN_DEBUG "Parsing Beacon/ProbeResp failed "
- "for " MACSTR "\n", MAC2STR(addr));
+ printk(KERN_DEBUG "Parsing %s failed "
+ "for " MAC_FMT "\n", (oid == DOT11_OID_BEACON ? "Beacon" : "ProbeResp"), MAC_ARG(addr));
return;
}
- if (pos[0] == WLAN_EID_GENERIC && pos[1] >= 4 &&
+ /* Don't forget RSN/WPA2 ! */
+ if (pos[0] == MFIE_TYPE_RSN && pos[1] > 4) {
+ prism54_wpa_bss_ie_add(priv, addr, pos, pos[1] + 2);
+ return;
+ }
+ if (pos[0] == MFIE_TYPE_GENERIC && pos[1] >= 4 &&
memcmp(pos + 2, wpa_oid, 4) == 0) {
prism54_wpa_bss_ie_add(priv, addr, pos, pos[1] + 2);
return;
@@ -2264,39 +2273,81 @@ handle_request(islpci_private *priv, str
}
static int
+prism54_process_sta_trap(islpci_private *priv, enum oid_num_t oid,
+ struct obj_mlmeex* mlmeex)
+{
+ struct obj_mlme *mlme = (struct obj_mlme*)mlmeex;
+ int ret = 0;
+
+ switch (oid) {
+ case DOT11_OID_DEAUTHENTICATEEX:
+ send_formatted_event(priv, "DeAuthenticate request",
+ mlme, 0);
+ break;
+
+ case DOT11_OID_AUTHENTICATEEX:
+ if (prism54_mac_accept(&priv->acl, mlmeex->address) &&
+ (mlmeex->state == DOT11_STATE_AUTH)) {
+
+ mlmeex->state = DOT11_STATE_ASSOCING;
+ mlmeex->code = 0;
+ mlmeex->size = 0;
+ ret = mgt_set_request(priv, DOT11_OID_ASSOCIATEEX,
+ 0, mlmeex);
+ if (ret)
+ return ret;
+ }
+ if (mlmeex->code != 0)
+ send_formatted_event(priv, "Authenticate request",
+ mlme, 1);
+ break;
+
+ case DOT11_OID_DISASSOCIATEEX:
+ send_formatted_event(priv, "Disassociate request",
+ mlme, 0);
+ break;
+
+ case DOT11_OID_ASSOCIATEEX:
+ if (mlmeex->code)
+ send_formatted_event(priv, "Associate request",
+ mlme, 1);
+ break;
+
+ case DOT11_OID_REASSOCIATEEX:
+ if (mlmeex->code)
+ send_formatted_event(priv, "Reassociate request",
+ mlme, 1);
+ break;
+
+ default:
+ printk(KERN_INFO "%s: Unhandled OID %x, "
+ "please fill a bug-report!\n", priv->ndev->name, oid);
+ break;
+ }
+
+ return ret;
+}
+
+static int
prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
char *data)
{
struct obj_mlme *mlme = (struct obj_mlme *) data;
struct obj_mlmeex *mlmeex = (struct obj_mlmeex *) data;
- struct obj_mlmeex *confirm;
- u8 wpa_ie[MAX_WPA_IE_LEN];
- int wpa_ie_len;
- size_t len = 0; /* u16, better? */
- u8 *payload = NULL, *pos = NULL;
- int ret;
-
- /* I think all trapable objects are listed here.
- * Some oids have a EX version. The difference is that they are emitted
- * in DOT11_MLME_EXTENDED mode (set with DOT11_OID_MLMEAUTOLEVEL)
- * with more info.
- * The few events already defined by the wireless tools are not really
- * suited. We use the more flexible custom event facility.
- */
-
- if (oid >= DOT11_OID_BEACON) {
- len = mlmeex->size;
- payload = pos = mlmeex->data;
- }
+ int ret = 0;
/* I fear prism54_process_bss_data won't work with big endian data */
- if ((oid == DOT11_OID_BEACON) || (oid == DOT11_OID_PROBE))
- prism54_process_bss_data(priv, oid, mlmeex->address,
- payload, len);
mgt_le_to_cpu(isl_oid[oid].flags & OID_FLAG_TYPE, (void *) mlme);
switch (oid) {
+ case DOT11_OID_BEACON:
+ case DOT11_OID_PROBE:
+ if (priv->iw_mode != IW_MODE_MASTER
+ && mlmeex->state != DOT11_STATE_AUTHING)
+ prism54_process_bss_data(priv, oid, mlmeex->address,
+ mlmeex->data, mlmeex->size);
+ break;
case GEN_OID_LINKSTATE:
link_changed(priv->ndev, (u32) *data);
@@ -2329,163 +2380,12 @@ prism54_process_trap_helper(islpci_priva
send_formatted_event(priv, "ReAssociate request", mlme, 1);
break;
- case DOT11_OID_BEACON:
- send_formatted_event(priv,
- "Received a beacon from an unkown AP",
- mlme, 0);
- break;
-
- case DOT11_OID_PROBE:
- /* we received a probe from a client. */
- send_formatted_event(priv, "Received a probe from client", mlme,
- 0);
- break;
-
- /* Note : "mlme" is actually a "struct obj_mlmeex *" here, but this
- * is backward compatible layout-wise with "struct obj_mlme".
- */
-
- case DOT11_OID_DEAUTHENTICATEEX:
- send_formatted_event(priv, "DeAuthenticate request", mlme, 0);
- break;
-
- case DOT11_OID_AUTHENTICATEEX:
- handle_request(priv, mlme, oid);
- send_formatted_event(priv, "Authenticate request (ex)", mlme, 1);
-
- if (priv->iw_mode != IW_MODE_MASTER
- && mlmeex->state != DOT11_STATE_AUTHING)
- break;
-
- confirm = kmalloc(sizeof(struct obj_mlmeex) + 6, GFP_ATOMIC);
-
- 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]
- );
- confirm->id = -1; /* or mlmeex->id ? */
- confirm->state = 0; /* not used */
- confirm->code = 0;
- confirm->size = 6;
- confirm->data[0] = 0x00;
- confirm->data[1] = 0x00;
- confirm->data[2] = 0x02;
- confirm->data[3] = 0x00;
- confirm->data[4] = 0x00;
- confirm->data[5] = 0x00;
-
- ret = mgt_set_varlen(priv, DOT11_OID_ASSOCIATEEX, confirm, 6);
-
- kfree(confirm);
- if (ret)
- return ret;
- break;
-
- case DOT11_OID_DISASSOCIATEEX:
- send_formatted_event(priv, "Disassociate request (ex)", mlme, 0);
- break;
-
- case DOT11_OID_ASSOCIATEEX:
- handle_request(priv, mlme, oid);
- send_formatted_event(priv, "Associate request (ex)", mlme, 1);
-
- if (priv->iw_mode != IW_MODE_MASTER
- && mlmeex->state != DOT11_STATE_ASSOCING)
- break;
-
- confirm = kmalloc(sizeof(struct obj_mlmeex), GFP_ATOMIC);
-
- if (!confirm)
- break;
-
- memcpy(&confirm->address, mlmeex->address, ETH_ALEN);
-
- confirm->id = ((struct obj_mlmeex *)mlme)->id;
- confirm->state = 0; /* not used */
- confirm->code = 0;
-
- 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]
- );
- kfree(confirm);
- break;
- }
-
- 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;
-
- 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
- && mlmeex->state != DOT11_STATE_ASSOCING)
- break;
-
- confirm = kmalloc(sizeof(struct obj_mlmeex), GFP_ATOMIC);
-
- if (!confirm)
- break;
-
- memcpy(&confirm->address, mlmeex->address, ETH_ALEN);
-
- confirm->id = mlmeex->id;
- confirm->state = 0; /* not used */
- confirm->code = 0;
-
- 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]
- );
- kfree(confirm);
- break;
- }
-
- 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:
- return -EINVAL;
+ ret = prism54_process_sta_trap(priv, oid, mlmeex);
+ break;
}
- return 0;
+ return ret;
}
/*
@@ -2521,368 +2421,33 @@ prism54_set_mac_address(struct net_devic
return ret;
}
-/* Note: currently, use hostapd ioctl from the Host AP driver for WPA
- * support. This is to be replaced with Linux wireless extensions once they
- * get WPA support. */
-
-/* Note II: please leave all this together as it will be easier to remove later,
- * once wireless extensions add WPA support -mcgrof */
-
-/* PRISM54_HOSTAPD ioctl() cmd: */
-enum {
- PRISM2_SET_ENCRYPTION = 6,
- PRISM2_HOSTAPD_SET_GENERIC_ELEMENT = 12,
- PRISM2_HOSTAPD_MLME = 13,
- PRISM2_HOSTAPD_SCAN_REQ = 14,
-};
-
-#define PRISM54_SET_WPA SIOCIWFIRSTPRIV+12
-#define PRISM54_HOSTAPD SIOCIWFIRSTPRIV+25
-#define PRISM54_DROP_UNENCRYPTED SIOCIWFIRSTPRIV+26
-
-#define PRISM2_HOSTAPD_MAX_BUF_SIZE 1024
-#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)
- * used in ioctl() */
-#define HOSTAP_CRYPT_ALG_NAME_LEN 16
-
-struct prism2_hostapd_param {
- u32 cmd;
- u8 sta_addr[ETH_ALEN];
- union {
- struct {
- u8 alg[HOSTAP_CRYPT_ALG_NAME_LEN];
- u32 flags;
- u32 err;
- u8 idx;
- u8 seq[8]; /* sequence counter (set: RX, get: TX) */
- u16 key_len;
- u8 key[0];
- } crypt;
- struct {
- u8 len;
- u8 data[0];
- } generic_elem;
- struct {
-#define MLME_STA_DEAUTH 0
-#define MLME_STA_DISASSOC 1
- u16 cmd;
- u16 reason_code;
- } mlme;
- struct {
- u8 ssid_len;
- u8 ssid[32];
- } scan_req;
- } u;
-};
-
-
-static int
-prism2_ioctl_set_encryption(struct net_device *dev,
- struct prism2_hostapd_param *param,
- int param_len)
-{
- islpci_private *priv = netdev_priv(dev);
- int rvalue = 0, force = 0;
- int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0;
- union oid_res_t r;
-
- /* with the new API, it's impossible to get a NULL pointer.
- * New version of iwconfig set the IW_ENCODE_NOKEY flag
- * when no key is given, but older versions don't. */
-
- if (param->u.crypt.key_len > 0) {
- /* we have a key to set */
- int index = param->u.crypt.idx;
- int current_index;
- struct obj_key key = { DOT11_PRIV_TKIP, 0, "" };
-
- /* get the current key index */
- rvalue = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
- current_index = r.u;
- /* Verify that the key is not marked as invalid */
- if (!(param->u.crypt.flags & IW_ENCODE_NOKEY)) {
- key.length = param->u.crypt.key_len > sizeof (param->u.crypt.key) ?
- sizeof (param->u.crypt.key) : param->u.crypt.key_len;
- memcpy(key.key, param->u.crypt.key, key.length);
- if (key.length == 32)
- /* we want WPA-PSK */
- key.type = DOT11_PRIV_TKIP;
- if ((index < 0) || (index > 3))
- /* no index provided use the current one */
- index = current_index;
-
- /* now send the key to the card */
- rvalue |=
- mgt_set_request(priv, DOT11_OID_DEFKEYX, index,
- &key);
- }
- /*
- * 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
- */
- if ((index == current_index) && (key.length > 0))
- force = 1;
- } else {
- int index = (param->u.crypt.flags & IW_ENCODE_INDEX) - 1;
- if ((index >= 0) && (index <= 3)) {
- /* we want to set the key index */
- rvalue |=
- mgt_set_request(priv, DOT11_OID_DEFKEYID, 0,
- &index);
- } else {
- if (!param->u.crypt.flags & IW_ENCODE_MODE) {
- /* we cannot do anything. Complain. */
- return -EINVAL;
- }
- }
- }
- /* now read the flags */
- if (param->u.crypt.flags & IW_ENCODE_DISABLED) {
- /* Encoding disabled,
- * authen = DOT11_AUTH_OS;
- * invoke = 0;
- * exunencrypt = 0; */
- }
- if (param->u.crypt.flags & IW_ENCODE_OPEN)
- /* Encode but accept non-encoded packets. No auth */
- invoke = 1;
- if ((param->u.crypt.flags & IW_ENCODE_RESTRICTED) || force) {
- /* Refuse non-encoded packets. Auth */
- authen = DOT11_AUTH_BOTH;
- invoke = 1;
- exunencrypt = 1;
- }
- /* do the change if requested */
- if ((param->u.crypt.flags & IW_ENCODE_MODE) || force) {
- rvalue |=
- mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
- rvalue |=
- mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &invoke);
- rvalue |=
- mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0,
- &exunencrypt);
- }
- return rvalue;
-}
-
-static int
-prism2_ioctl_set_generic_element(struct net_device *ndev,
- struct prism2_hostapd_param *param,
- int param_len)
-{
- islpci_private *priv = netdev_priv(ndev);
- int max_len, len, alen, ret=0;
- struct obj_attachment *attach;
-
- len = param->u.generic_elem.len;
- max_len = param_len - PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN;
- if (max_len < 0 || max_len < len)
- return -EINVAL;
-
- alen = sizeof(*attach) + len;
- attach = kmalloc(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
-
- /* Note: endianness is covered by mgt_set_varlen */
-
- attach->type = (WLAN_FC_TYPE_MGMT << 2) |
- (WLAN_FC_STYPE_ASSOC_REQ << 4);
- attach->id = -1;
- attach->size = len;
- memcpy(attach->data, param->u.generic_elem.data, len);
-
- ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach, len);
-
- if (ret == 0) {
- attach->type = (WLAN_FC_TYPE_MGMT << 2) |
- (WLAN_FC_STYPE_REASSOC_REQ << 4);
-
- ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach, len);
-
- if (ret == 0)
- printk(KERN_DEBUG "%s: WPA IE Attachment was set\n",
- ndev->name);
- }
-
- kfree(attach);
- return ret;
-
-}
-
-static int
-prism2_ioctl_mlme(struct net_device *dev, struct prism2_hostapd_param *param)
-{
- return -EOPNOTSUPP;
-}
-
-static int
-prism2_ioctl_scan_req(struct net_device *ndev,
- struct prism2_hostapd_param *param)
-{
- islpci_private *priv = netdev_priv(ndev);
- int i, rvalue;
- struct obj_bsslist *bsslist;
- u32 noise = 0;
- char *extra = "";
- char *current_ev = "foo";
- union oid_res_t r;
-
- if (islpci_get_state(priv) < PRV_STATE_INIT) {
- /* device is not ready, fail gently */
- return 0;
- }
-
- /* first get the noise value. We will use it to report the link quality */
- rvalue = mgt_get_request(priv, DOT11_OID_NOISEFLOOR, 0, NULL, &r);
- noise = r.u;
-
- /* Ask the device for a list of known bss. We can report at most
- * IW_MAX_AP=64 to the range struct. 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 < min(IW_MAX_AP, (int) bsslist->nr); i++)
- current_ev = prism54_translate_bss(ndev, current_ev,
- extra + IW_SCAN_MAX_DATA,
- &(bsslist->bsslist[i]),
- noise);
- kfree(bsslist);
-
- return rvalue;
-}
-
-static int
-prism54_hostapd(struct net_device *ndev, struct iw_point *p)
-{
- struct prism2_hostapd_param *param;
- int ret = 0;
- u32 uwrq;
-
- printk(KERN_DEBUG "prism54_hostapd - len=%d\n", p->length);
- if (p->length < sizeof(struct prism2_hostapd_param) ||
- p->length > PRISM2_HOSTAPD_MAX_BUF_SIZE || !p->pointer)
- return -EINVAL;
-
- param = (struct prism2_hostapd_param *) kmalloc(p->length, GFP_KERNEL);
- if (param == NULL)
- return -ENOMEM;
-
- if (copy_from_user(param, p->pointer, p->length)) {
- kfree(param);
- return -EFAULT;
- }
-
- switch (param->cmd) {
- case PRISM2_SET_ENCRYPTION:
- printk(KERN_DEBUG "%s: Caught WPA supplicant set encryption request\n",
- ndev->name);
- ret = prism2_ioctl_set_encryption(ndev, param, p->length);
- break;
- case PRISM2_HOSTAPD_SET_GENERIC_ELEMENT:
- printk(KERN_DEBUG "%s: Caught WPA supplicant set WPA IE request\n",
- ndev->name);
- ret = prism2_ioctl_set_generic_element(ndev, param,
- p->length);
- break;
- case PRISM2_HOSTAPD_MLME:
- printk(KERN_DEBUG "%s: Caught WPA supplicant MLME request\n",
- ndev->name);
- ret = prism2_ioctl_mlme(ndev, param);
- break;
- case PRISM2_HOSTAPD_SCAN_REQ:
- printk(KERN_DEBUG "%s: Caught WPA supplicant scan request\n",
- ndev->name);
- ret = prism2_ioctl_scan_req(ndev, param);
- break;
- case PRISM54_SET_WPA:
- printk(KERN_DEBUG "%s: Caught WPA supplicant wpa init request\n",
- ndev->name);
- uwrq = 1;
- ret = prism54_set_wpa(ndev, NULL, &uwrq, NULL);
- break;
- case PRISM54_DROP_UNENCRYPTED:
- printk(KERN_DEBUG "%s: Caught WPA drop unencrypted request\n",
- ndev->name);
-#if 0
- uwrq = 0x01;
- mgt_set(priv, DOT11_OID_EXUNENCRYPTED, &uwrq);
- down_write(&priv->mib_sem);
- mgt_commit(priv);
- up_write(&priv->mib_sem);
-#endif
- /* Not necessary, as set_wpa does it, should we just do it here though? */
- ret = 0;
- break;
- default:
- printk(KERN_DEBUG "%s: Caught a WPA supplicant request that is not supported\n",
- ndev->name);
- ret = -EOPNOTSUPP;
- break;
- }
-
- if (ret == 0 && copy_to_user(p->pointer, param, p->length))
- ret = -EFAULT;
-
- kfree(param);
-
- return ret;
-}
-
static int
prism54_set_wpa(struct net_device *ndev, struct iw_request_info *info,
__u32 * uwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
- u32 mlme, authen, dot1x, filter, wep;
+ u32 mlme, dot1x;
if (islpci_get_state(priv) < PRV_STATE_INIT)
return 0;
- wep = 1; /* For privacy invoked */
- filter = 1; /* Filter out all unencrypted frames */
- dot1x = 0x01; /* To enable eap filter */
- mlme = DOT11_MLME_EXTENDED;
- authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
+ dot1x = 0; // disable global filtering
+ mlme = DOT11_MLME_AUTO;
down_write(&priv->mib_sem);
priv->wpa = *uwrq;
- switch (priv->wpa) {
- default:
- case 0: /* Clears/disables WPA and friends */
- wep = 0;
- filter = 0; /* Do not filter un-encrypted data */
- dot1x = 0;
- mlme = DOT11_MLME_AUTO;
- printk("%s: Disabling WPA\n", ndev->name);
- break;
- case 2:
- case 1: /* WPA */
- printk("%s: Enabling WPA\n", ndev->name);
- break;
+ if (priv->wpa) {
+ if (priv->iw_mode == IW_MODE_MASTER)
+ dot1x = 1;
+ mlme = DOT11_MLME_EXTENDED;
}
up_write(&priv->mib_sem);
- mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
- mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &wep);
- mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0, &filter);
mgt_set_request(priv, DOT11_OID_DOT1XENABLE, 0, &dot1x);
mgt_set_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, &mlme);
- return 0;
+ return prism54_set_auth_alg(priv, IW_ENCODE_OPEN);
}
static int
@@ -2890,7 +2455,9 @@ prism54_get_wpa(struct net_device *ndev,
__u32 * uwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
+ down_write(&priv->mib_sem);
*uwrq = priv->wpa;
+ up_write(&priv->mib_sem);
return 0;
}
@@ -3025,6 +2592,80 @@ prism54_set_spy(struct net_device *ndev,
return iw_handler_set_spy(ndev, info, uwrq, extra);
}
+static int
+prism54_send_mlme(struct net_device *ndev, struct iw_request_info *info,
+ struct iw_point *dwrq, char *extra)
+{
+ islpci_private *priv = netdev_priv(ndev);
+ struct iw_mlme *iwmlme;
+ struct obj_mlme mlme;
+ struct obj_sta *sta;
+ union oid_res_t r;
+ int ret = 0;
+
+ if (dwrq->length != sizeof(*iwmlme))
+ return -EINVAL;
+
+ iwmlme = (struct iw_mlme*)extra;
+
+ if (iwmlme->addr.sa_family != ARPHRD_ETHER)
+ return -EINVAL;
+
+ /* get STA/AP Id.
+ or the card will BROADCAST the packet! */
+
+ sta = (struct obj_sta*)kzalloc(sizeof(*sta), GFP_KERNEL);
+ if (!sta)
+ return -ENOMEM;
+
+ memcpy(sta->address, iwmlme->addr.sa_data, ETH_ALEN);
+ ret = mgt_get_request(priv, DOT11_OID_CLIENTFIND, 0, sta, &r);
+ kfree(sta);
+
+ if (ret) {
+ sta = r.ptr;
+ memcpy(mlme.address, iwmlme->addr.sa_data, ETH_ALEN);
+
+ if (sta->node >= 1)
+ mlme.id = sta->node;
+ else
+ mlme.id = -1;
+ } else
+ /* use broadcast id */
+ mlme.id = -1;
+
+ mlme.code = iwmlme->reason_code;
+
+ kfree(r.ptr);
+ switch (iwmlme->cmd) {
+ case IW_MLME_DEAUTH:
+ mlme.state = DOT11_STATE_NONE;
+ return mgt_set_request(priv, DOT11_OID_DEAUTHENTICATE,
+ 0, &mlme);
+ break;
+ case IW_MLME_DISASSOC:
+ mlme.state = DOT11_STATE_NONE;
+ return mgt_set_request(priv, DOT11_OID_DISASSOCIATE,
+ 0, &mlme);
+ break;
+#if 0
+ /* not in WEXT yet */
+ case IW_MLME_AUTH:
+ mlme.state = DOT11_STATE_AUTH;
+ return mgt_set_request(priv, DOT11_OID_AUTHENTICATE,
+ 0, &mlme);
+ break;
+ case IW_MLME_ASSOC:
+ mlme.state = DOT11_STATE_ASSOC;
+ return mgt_set_request(priv, DOT11_OID_ASSOCIATE,
+ 0, &mlme);
+ break;
+#endif
+ }
+
+ return -EOPNOTSUPP;
+}
+
static const iw_handler prism54_handler[] = {
(iw_handler) prism54_commit, /* SIOCSIWCOMMIT */
(iw_handler) prism54_get_name, /* SIOCGIWNAME */
@@ -3042,13 +2683,13 @@ static const iw_handler prism54_handler[
(iw_handler) NULL, /* SIOCGIWPRIV */
(iw_handler) NULL, /* SIOCSIWSTATS */
(iw_handler) NULL, /* SIOCGIWSTATS */
- prism54_set_spy, /* SIOCSIWSPY */
+ (iw_handler) prism54_set_spy, /* SIOCSIWSPY */
iw_handler_get_spy, /* SIOCGIWSPY */
iw_handler_set_thrspy, /* SIOCSIWTHRSPY */
iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
(iw_handler) prism54_set_wap, /* SIOCSIWAP */
(iw_handler) prism54_get_wap, /* SIOCGIWAP */
- (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) prism54_send_mlme, /* SIOCSIWMLME */
(iw_handler) NULL, /* SIOCGIWAPLIST depreciated */
(iw_handler) prism54_set_scan, /* SIOCSIWSCAN */
(iw_handler) prism54_get_scan, /* SIOCGIWSCAN */
@@ -3072,15 +2713,15 @@ static const iw_handler prism54_handler[
(iw_handler) prism54_get_encode, /* SIOCGIWENCODE */
(iw_handler) NULL, /* SIOCSIWPOWER */
(iw_handler) NULL, /* SIOCGIWPOWER */
- NULL, /* -- hole -- */
- NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
(iw_handler) prism54_set_genie, /* SIOCSIWGENIE */
(iw_handler) prism54_get_genie, /* SIOCGIWGENIE */
(iw_handler) prism54_set_auth, /* SIOCSIWAUTH */
(iw_handler) prism54_get_auth, /* SIOCGIWAUTH */
- (iw_handler) prism54_set_encodeext, /* SIOCSIWENCODEEXT */
- (iw_handler) prism54_get_encodeext, /* SIOCGIWENCODEEXT */
- NULL, /* SIOCSIWPMKSA */
+ (iw_handler) prism54_set_encodeext, /* SIOCSIWENCODEEXT */
+ (iw_handler) prism54_get_encodeext, /* SIOCGIWENCODEEXT */
+ (iw_handler) NULL /* SIOCSIWPMKSA */
};
/* The low order bit identify a SET (0) or a GET (1) ioctl. */
@@ -3259,14 +2900,5 @@ const struct iw_handler_def prism54_hand
int
prism54_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
{
- struct iwreq *wrq = (struct iwreq *) rq;
- int ret = -1;
- switch (cmd) {
- case PRISM54_HOSTAPD:
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- ret = prism54_hostapd(ndev, &wrq->u.data);
- return ret;
- }
return -EOPNOTSUPP;
}
diff --git a/drivers/net/wireless/prism54/isl_ioctl.h b/drivers/net/wireless/prism54/isl_ioctl.h
index e8183d3..8322133 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.h
+++ b/drivers/net/wireless/prism54/isl_ioctl.h
@@ -1,4 +1,5 @@
/*
+ *
* Copyright (C) 2002 Intersil Americas Inc.
* (C) 2003 Aurelien Alleaume <slts@free.fr>
* (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
@@ -21,12 +22,11 @@
#ifndef _ISL_IOCTL_H
#define _ISL_IOCTL_H
+#include <net/iw_handler.h> /* New driver API */
#include "islpci_mgt.h"
#include "islpci_dev.h"
-#include <net/iw_handler.h> /* New driver API */
-
-#define SUPPORTED_WIRELESS_EXT 19
+#define SUPPORTED_WIRELESS_EXT 21
void prism54_mib_init(islpci_private *);
diff --git a/drivers/net/wireless/prism54/isl_oid.h b/drivers/net/wireless/prism54/isl_oid.h
index b7534c2..88b24d6 100644
--- a/drivers/net/wireless/prism54/isl_oid.h
+++ b/drivers/net/wireless/prism54/isl_oid.h
@@ -2,6 +2,7 @@
* Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
* Copyright (C) 2004 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
* Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
+ * Copyright (C) 2006 Christian Lamparter <chunkeey@web.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,29 +27,67 @@ #define _ISL_OID_H
* with the device firmware
*/
+#define MAX_KEY_LEN 32
+
struct obj_ssid {
u8 length;
- char octets[33];
+ u8 octets[IW_ESSID_MAX_SIZE + 1];
} __attribute__ ((packed));
+enum dot11_priv_t {
+ DOT11_PRIV_WEP = 0,
+ DOT11_PRIV_TKIP = 1
+};
+
struct obj_key {
u8 type; /* dot11_priv_t */
u8 length;
- char key[32];
+ u8 key[MAX_KEY_LEN];
} __attribute__ ((packed));
+enum dot11_stakey_opt_t {
+ DOT11_STAKEY_OPTION_GROUPKEY = 0x0000,
+ DOT11_STAKEY_OPTION_DEFAULTKEY = 0x0001
+};
+
+enum dot11_keyop_t {
+ DOT11_KEYOP_SET_KEY = 0x0000,
+ DOT11_KEYOP_REMOVE_KEY = 0x0001
+};
+
+struct obj_stakey {
+ u8 address[ETH_ALEN];
+ u8 keyid;
+ u8 reserved; /* dot11_keyop_t */
+ u16 options; /* dot11_stakey_opt_t */
+ u8 type; /* dot11_priv_t */
+ u8 length;
+ u8 key[MAX_KEY_LEN];
+} __attribute__ ((packed));
+
+enum dot11_state_t {
+ DOT11_STATE_NONE = 0,
+ DOT11_STATE_AUTHING = 1,
+ DOT11_STATE_AUTH = 2,
+ DOT11_STATE_ASSOCING = 3,
+ DOT11_STATE_REASSOC = 4,
+ DOT11_STATE_ASSOC = 5,
+ DOT11_STATE_IBSS = 6,
+ DOT11_STATE_WDS = 7
+};
+
struct obj_mlme {
- u8 address[6];
+ u8 address[ETH_ALEN];
u16 id;
- u16 state;
- u16 code;
+ u16 state; /* dot11_state_t */
+ u16 code; /* WLAN_STATUS_ / WLAN_REASON_ */
} __attribute__ ((packed));
struct obj_mlmeex {
- u8 address[6];
+ u8 address[ETH_ALEN];
u16 id;
- u16 state;
- u16 code;
+ u16 state; /* dot11_state_t */
+ u16 code; /* WLAN_STATUS_ / WLAN_REASON_ */
u16 size;
u8 data[0];
} __attribute__ ((packed));
@@ -59,23 +98,23 @@ struct obj_buffer {
} __attribute__ ((packed));
struct obj_bss {
- u8 address[6];
+ u8 address[ETH_ALEN];
int:16; /* padding */
- char state;
- char reserved;
- short age;
+ u8 state; /* dot11_state_t */
+ u8 reserved;
+ u16 age;
- char quality;
- char rssi;
+ u8 quality;
+ u8 rssi;
struct obj_ssid ssid;
- short channel;
- char beacon_period;
- char dtim_period;
- short capinfo;
- short rates;
- short basic_rates;
+ u16 channel;
+ u8 beacon_period;
+ u8 dtim_period;
+ u16 capinfo; /* WLAN_CAPABILITY_ */
+ u16 rates;
+ u16 basic_rates;
int:16; /* padding */
} __attribute__ ((packed));
@@ -90,14 +129,33 @@ struct obj_frequencies {
} __attribute__ ((packed));
struct obj_attachment {
- char type;
- char reserved;
- short id;
- short size;
- char data[0];
+ u8 type; /* IEEE80211_STYPE_ */
+ u8 reserved;
+ u16 id;
+ u16 size;
+ u8 data[0];
} __attribute__((packed));
-/*
+struct obj_stasc {
+ u8 address[ETH_ALEN];
+ u8 keyid;
+ u8 tx_sc;
+ u8 sc[6];
+} __attribute__ ((packed));
+
+struct obj_sta {
+ u8 address[ETH_ALEN];
+ int:16;
+ u8 state; /* dot11_state_t */
+ u8 node; /* Station ID */
+ u16 age;
+ u8 reserved1;
+ u8 rssi;
+ u8 rate;
+ u8 reserved2;
+} __attribute__ ((packed));
+
+/*
* in case everything's ok, the inlined function below will be
* optimized away by the compiler...
*/
@@ -112,19 +170,12 @@ __bug_on_wrong_struct_sizes(void)
BUILD_BUG_ON(sizeof (struct obj_bss) != 60);
BUILD_BUG_ON(sizeof (struct obj_bsslist) != 4);
BUILD_BUG_ON(sizeof (struct obj_frequencies) != 2);
+ BUILD_BUG_ON(sizeof (struct obj_sta) != 16);
+ BUILD_BUG_ON(sizeof (struct obj_stasc) != 14);
+ BUILD_BUG_ON(sizeof (struct obj_stakey) != 44);
+ BUILD_BUG_ON(sizeof (struct obj_attachment) != 6);
}
-enum dot11_state_t {
- DOT11_STATE_NONE = 0,
- DOT11_STATE_AUTHING = 1,
- DOT11_STATE_AUTH = 2,
- DOT11_STATE_ASSOCING = 3,
-
- DOT11_STATE_ASSOC = 5,
- DOT11_STATE_IBSS = 6,
- DOT11_STATE_WDS = 7
-};
-
enum dot11_bsstype_t {
DOT11_BSSTYPE_NONE = 0,
DOT11_BSSTYPE_INFRA = 1,
@@ -145,11 +196,6 @@ enum dot11_mlme_t {
DOT11_MLME_EXTENDED = 2
};
-enum dot11_priv_t {
- DOT11_PRIV_WEP = 0,
- DOT11_PRIV_TKIP = 1
-};
-
/* Prism "Nitro" / Frameburst / "Packet Frame Grouping"
* Value is in microseconds. Represents the # microseconds
* the firmware will take to group frames before sending out then out
@@ -464,31 +510,32 @@ enum oid_num_t {
OID_NUM_LAST
};
-#define OID_FLAG_CACHED 0x80
-#define OID_FLAG_TYPE 0x7f
-
-#define OID_TYPE_U32 0x01
-#define OID_TYPE_SSID 0x02
-#define OID_TYPE_KEY 0x03
-#define OID_TYPE_BUFFER 0x04
-#define OID_TYPE_BSS 0x05
-#define OID_TYPE_BSSLIST 0x06
-#define OID_TYPE_FREQUENCIES 0x07
-#define OID_TYPE_MLME 0x08
-#define OID_TYPE_MLMEEX 0x09
-#define OID_TYPE_ADDR 0x0A
-#define OID_TYPE_RAW 0x0B
-#define OID_TYPE_ATTACH 0x0C
-
-/* OID_TYPE_MLMEEX is special because of a variable size field when sending.
- * Not yet implemented (not used in driver anyway).
- */
+enum oid_types_t {
+ OID_TYPE_U32 = 0x01,
+ OID_TYPE_SSID = 0x02,
+ OID_TYPE_KEY = 0x03,
+ OID_TYPE_BUFFER = 0x04,
+ OID_TYPE_BSS = 0x05,
+ OID_TYPE_BSSLIST = 0x06,
+ OID_TYPE_FREQUENCIES = 0x07,
+ OID_TYPE_MLME = 0x08,
+ OID_TYPE_MLMEEX = 0x09,
+ OID_TYPE_ADDR = 0x0A,
+ OID_TYPE_RAW = 0x0B,
+ OID_TYPE_ATTACH = 0x0C,
+ OID_TYPE_STASC = 0x0D,
+ OID_TYPE_STAKEY = 0x0E,
+ OID_TYPE_STAINFO = 0x0F,
+
+ OID_FLAG_CACHED = 0x80,
+ OID_FLAG_TYPE = 0x7f
+};
struct oid_t {
enum oid_num_t oid;
- short range; /* to define a range of oid */
- short size; /* max size of the associated data */
- char flags;
+ u16 range; /* to define a range of oid */
+ u16 size; /* max size of the associated data */
+ enum oid_types_t flags;
};
union oid_res_t {
@@ -496,8 +543,8 @@ union oid_res_t {
u32 u;
};
-#define IWMAX_BITRATES 20
-#define IWMAX_BSS 24
+#define IWMAX_BITRATES 20
+#define IWMAX_BSS 24
#define IWMAX_FREQ 30
#define PRIV_STR_SIZE 1024
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
index 1e0603c..e6d9b26 100644
--- a/drivers/net/wireless/prism54/islpci_dev.c
+++ b/drivers/net/wireless/prism54/islpci_dev.c
@@ -25,10 +25,10 @@ #include <linux/pci.h>
#include <linux/etherdevice.h>
#include <linux/delay.h>
#include <linux/if_arp.h>
+#include <linux/firmware.h>
#include <asm/io.h>
-#include "prismcompat.h"
#include "isl_38xx.h"
#include "isl_ioctl.h"
#include "islpci_dev.h"
@@ -86,7 +86,7 @@ isl_upload_firmware(islpci_private *priv
long fw_len;
const u32 *fw_ptr;
- rc = request_firmware(&fw_entry, priv->firmware, PRISM_FW_PDEV);
+ rc = request_firmware(&fw_entry, priv->firmware, &priv->pdev->dev);
if (rc) {
printk(KERN_ERR
"%s: request_firmware() failed for '%s'\n",
diff --git a/drivers/net/wireless/prism54/islpci_dev.h b/drivers/net/wireless/prism54/islpci_dev.h
index a9aa166..3d0bb8f 100644
--- a/drivers/net/wireless/prism54/islpci_dev.h
+++ b/drivers/net/wireless/prism54/islpci_dev.h
@@ -71,7 +71,6 @@ struct islpci_bss_wpa_ie {
u8 bssid[ETH_ALEN];
u8 wpa_ie[MAX_WPA_IE_LEN];
size_t wpa_ie_len;
-
};
typedef struct {
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
index 676d838..6da1f86 100644
--- a/drivers/net/wireless/prism54/islpci_eth.c
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -24,7 +24,6 @@ #include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
-#include "prismcompat.h"
#include "isl_38xx.h"
#include "islpci_eth.h"
#include "islpci_mgt.h"
@@ -482,8 +481,7 @@ #endif
void
islpci_do_reset_and_wake(void *data)
{
- islpci_private *priv = data;
-
+ islpci_private *priv = (islpci_private *) data;
islpci_reset(priv, 1);
priv->reset_task_pending = 0;
smp_wmb();
@@ -500,13 +498,12 @@ islpci_eth_tx_timeout(struct net_device
statistics->tx_errors++;
if (!priv->reset_task_pending) {
- printk(KERN_WARNING
- "%s: tx_timeout, scheduling reset", ndev->name);
+ printk(KERN_WARNING "%s: tx_timeout\n", ndev->name);
netif_stop_queue(ndev);
priv->reset_task_pending = 1;
schedule_work(&priv->reset_task);
} else {
printk(KERN_WARNING
- "%s: tx_timeout, waiting for reset", ndev->name);
+ "%s: tx_timeout, waiting for reset\n", ndev->name);
}
}
diff --git a/drivers/net/wireless/prism54/islpci_eth.h b/drivers/net/wireless/prism54/islpci_eth.h
diff --git a/drivers/net/wireless/prism54/islpci_hotplug.c b/drivers/net/wireless/prism54/islpci_hotplug.c
index f6354b1..0e07c2b 100644
--- a/drivers/net/wireless/prism54/islpci_hotplug.c
+++ b/drivers/net/wireless/prism54/islpci_hotplug.c
@@ -23,7 +23,6 @@ #include <linux/delay.h>
#include <linux/init.h> /* For __init, __exit */
#include <linux/dma-mapping.h>
-#include "prismcompat.h"
#include "islpci_dev.h"
#include "islpci_mgt.h" /* for pc_debug */
#include "isl_oid.h"
@@ -170,7 +169,8 @@ #endif
pci_set_master(pdev);
/* enable MWI */
- pci_set_mwi(pdev);
+ if (pci_set_mwi(pdev))
+ printk(KERN_ERR "%s: pci_set_mwi failed\n", DRV_NAME);
/* setup the network device interface and its structure */
if (!(ndev = islpci_setup(pdev))) {
@@ -289,7 +289,10 @@ prism54_resume(struct pci_dev *pdev)
islpci_private *priv = ndev ? netdev_priv(ndev) : NULL;
BUG_ON(!priv);
- pci_enable_device(pdev);
+ if (pci_enable_device(pdev)) {
+ printk(KERN_ERR "%s: pci_enable_device() failed.\n", DRV_NAME);
+ return -ENODEV;
+ }
printk(KERN_NOTICE "%s: got resume request\n", ndev->name);
diff --git a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c
index 036a875..8fd781d 100644
--- a/drivers/net/wireless/prism54/islpci_mgt.c
+++ b/drivers/net/wireless/prism54/islpci_mgt.c
@@ -25,7 +25,6 @@ #include <asm/io.h>
#include <asm/system.h>
#include <linux/if_arp.h>
-#include "prismcompat.h"
#include "isl_38xx.h"
#include "islpci_mgt.h"
#include "isl_oid.h" /* additional types and defs for isl38xx fw */
diff --git a/drivers/net/wireless/prism54/islpci_mgt.h b/drivers/net/wireless/prism54/islpci_mgt.h
diff --git a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c
index fbc52b6..24b5a49 100644
--- a/drivers/net/wireless/prism54/oid_mgt.c
+++ b/drivers/net/wireless/prism54/oid_mgt.c
@@ -16,7 +16,6 @@
*
*/
-#include "prismcompat.h"
#include "islpci_dev.h"
#include "islpci_mgt.h"
#include "isl_oid.h"
@@ -85,9 +84,9 @@ struct oid_t isl_oid[] = {
OID_U32_C(DOT11_OID_DEFKEYID, 0x12000003),
[DOT11_OID_DEFKEYX] = {0x12000004, 3, sizeof (struct obj_key),
OID_FLAG_CACHED | OID_TYPE_KEY}, /* DOT11_OID_DEFKEY1,...DOT11_OID_DEFKEY4 */
- OID_UNKNOWN(DOT11_OID_STAKEY, 0x12000008),
+ OID_STRUCT(DOT11_OID_STAKEY, 0x12000008, struct obj_stakey, OID_TYPE_STAKEY),
OID_U32(DOT11_OID_REKEYTHRESHOLD, 0x12000009),
- OID_UNKNOWN(DOT11_OID_STASC, 0x1200000a),
+ OID_STRUCT(DOT11_OID_STASC, 0x1200000a, struct obj_stasc, OID_TYPE_STASC),
OID_U32(DOT11_OID_PRIVTXREJECTED, 0x1a000000),
OID_U32(DOT11_OID_PRIVRXPLAIN, 0x1a000001),
@@ -122,9 +121,10 @@ struct oid_t isl_oid[] = {
OID_U32(DOT11_OID_BRIDGELOCAL, 0x15000000),
OID_U32(DOT11_OID_CLIENTS, 0x15000001),
OID_U32(DOT11_OID_CLIENTSASSOCIATED, 0x15000002),
- [DOT11_OID_CLIENTX] = {0x15000003, 2006, 0, 0}, /* DOT11_OID_CLIENTX,...DOT11_OID_CLIENT2007 */
+ [DOT11_OID_CLIENTX] = {0x15000003, 2006, sizeof(struct obj_sta),
+ OID_TYPE_STAINFO}, /* DOT11_OID_CLIENTX,...DOT11_OID_CLIENT2007 */
- OID_STRUCT(DOT11_OID_CLIENTFIND, 0x150007DB, u8[6], OID_TYPE_ADDR),
+ OID_STRUCT(DOT11_OID_CLIENTFIND, 0x150007DB, struct obj_sta, OID_TYPE_STAINFO),
OID_STRUCT(DOT11_OID_WDSLINKADD, 0x150007DC, u8[6], OID_TYPE_ADDR),
OID_STRUCT(DOT11_OID_WDSLINKREMOVE, 0x150007DD, u8[6], OID_TYPE_ADDR),
OID_STRUCT(DOT11_OID_EAPAUTHSTA, 0x150007DE, u8[6], OID_TYPE_ADDR),
@@ -201,8 +201,7 @@ struct oid_t isl_oid[] = {
OID_U32(DOT11_OID_STATIMEOUT, 0x19000000),
OID_U32_C(DOT11_OID_MLMEAUTOLEVEL, 0x19000001),
OID_U32(DOT11_OID_BSSTIMEOUT, 0x19000002),
- [DOT11_OID_ATTACHMENT] = {0x19000003, 0,
- sizeof(struct obj_attachment), OID_TYPE_ATTACH},
+ OID_STRUCT_C(DOT11_OID_ATTACHMENT, 0x19000003, sizeof(struct obj_attachment), OID_TYPE_ATTACH),
OID_STRUCT_C(DOT11_OID_PSMBUFFER, 0x19000004, struct obj_buffer,
OID_TYPE_BUFFER),
@@ -277,7 +276,7 @@ mgt_clean(islpci_private *priv)
}
void
-mgt_le_to_cpu(int type, void *data)
+mgt_le_to_cpu(enum oid_types_t type, void *data)
{
switch (type) {
case OID_TYPE_U32:
@@ -334,19 +333,31 @@ mgt_le_to_cpu(int type, void *data)
attach->id = le16_to_cpu(attach->id);
attach->size = le16_to_cpu(attach->size);
break;
- }
+ }
+ case OID_TYPE_STAKEY: {
+ struct obj_stakey *stakey = data;
+ stakey->options = le16_to_cpu(stakey->options);
+ break;
+ }
+ case OID_TYPE_STAINFO: {
+ struct obj_sta *sta = data;
+ sta->age = le16_to_cpu(sta->age);
+ break;
+ }
case OID_TYPE_SSID:
case OID_TYPE_KEY:
case OID_TYPE_ADDR:
case OID_TYPE_RAW:
+ case OID_TYPE_STASC:
break;
default:
BUG();
+ break;
}
}
static void
-mgt_cpu_to_le(int type, void *data)
+mgt_cpu_to_le(enum oid_types_t type, void *data)
{
switch (type) {
case OID_TYPE_U32:
@@ -403,14 +414,26 @@ mgt_cpu_to_le(int type, void *data)
attach->id = cpu_to_le16(attach->id);
attach->size = cpu_to_le16(attach->size);
break;
- }
+ }
+ case OID_TYPE_STAKEY: {
+ struct obj_stakey *stakey = data;
+ stakey->options = cpu_to_le16(stakey->options);
+ break;
+ }
+ case OID_TYPE_STAINFO: {
+ struct obj_sta *sta = data;
+ sta->age = cpu_to_le16(sta->age);
+ break;
+ }
case OID_TYPE_SSID:
case OID_TYPE_KEY:
case OID_TYPE_ADDR:
case OID_TYPE_RAW:
+ case OID_TYPE_STASC:
break;
default:
BUG();
+ break;
}
}
@@ -658,13 +681,16 @@ static enum oid_num_t commit_part1[] = {
static enum oid_num_t commit_part2[] = {
DOT11_OID_SSID,
+ /* problematic with WPA
DOT11_OID_PSMBUFFER,
+ */
DOT11_OID_AUTHENABLE,
DOT11_OID_PRIVACYINVOKED,
DOT11_OID_EXUNENCRYPTED,
DOT11_OID_DEFKEYX, /* MULTIPLE */
DOT11_OID_DEFKEYID,
DOT11_OID_DOT1XENABLE,
+ DOT11_OID_ATTACHMENT,
OID_INL_DOT11D_CONFORMANCE,
/* Do not initialize this - fw < 1.0.4.3 rejects it
OID_INL_OUTPUTPOWER,
diff --git a/drivers/net/wireless/prism54/oid_mgt.h b/drivers/net/wireless/prism54/oid_mgt.h
index 92c8a2d..10a5cc3 100644
--- a/drivers/net/wireless/prism54/oid_mgt.h
+++ b/drivers/net/wireless/prism54/oid_mgt.h
@@ -32,7 +32,7 @@ void mgt_clean(islpci_private *);
extern const int frequency_list_a[];
int channel_of_freq(int);
-void mgt_le_to_cpu(int, void *);
+void mgt_le_to_cpu(enum oid_types_t, void *);
int mgt_set_request(islpci_private *, enum oid_num_t, int, void *);
int mgt_set_varlen(islpci_private *, enum oid_num_t, void *, int);
diff --git a/drivers/net/wireless/prism54/prismcompat.h b/drivers/net/wireless/prism54/prismcompat.h
deleted file mode 100644
index aa1d174..0000000
--- a/drivers/net/wireless/prism54/prismcompat.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * (C) 2004 Margit Schubert-While <margitsw@t-online.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/*
- * Compatibility header file to aid support of different kernel versions
- */
-
-#ifdef PRISM54_COMPAT24
-#include "prismcompat24.h"
-#else /* PRISM54_COMPAT24 */
-
-#ifndef _PRISM_COMPAT_H
-#define _PRISM_COMPAT_H
-
-#include <linux/device.h>
-#include <linux/firmware.h>
-#include <linux/moduleparam.h>
-#include <linux/workqueue.h>
-#include <linux/compiler.h>
-
-#ifndef __iomem
-#define __iomem
-#endif
-
-#define PRISM_FW_PDEV &priv->pdev->dev
-
-#endif /* _PRISM_COMPAT_H */
-#endif /* PRISM54_COMPAT24 */
diff --git a/scripts/package/Makefile b/scripts/package/Makefile
diff --git a/scripts/package/builddeb b/scripts/package/builddeb
diff --git a/scripts/package/buildtar b/scripts/package/buildtar
diff --git a/scripts/package/mkspec b/scripts/package/mkspec
^ permalink raw reply related [flat|nested] 39+ messages in thread
* Re: [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
2006-10-31 16:05 ` Dan Williams
2006-10-31 17:53 ` chunkeey
@ 2006-11-03 14:49 ` Dan Williams
2006-11-03 16:06 ` Luis R. Rodriguez
1 sibling, 1 reply; 39+ messages in thread
From: Dan Williams @ 2006-11-03 14:49 UTC (permalink / raw)
To: Luis R. Rodriguez; +Cc: chunkeey@web.de, John W. Linville, netdev
On Tue, 2006-10-31 at 11:05 -0500, Dan Williams wrote:
> On Mon, 2006-10-30 at 15:17 -0500, Luis R. Rodriguez wrote:
> > On 10/29/06, chunkeey@web.de <chunkeey@web.de> wrote:
> > > This patch completes WPA/RSN with TKIP support for all fullmac prism54 cards.
> > > I removed all parts which are not relevant for wpa_supplicant (managed mode).
> >
> > This is great effort and thanks for it! My only concern with the patch
> > is breaking compatiblity with 2.4 but then again I'm tired of having
> > to keep this compat work up too and soon, after d80211 full force push
> > it may not be possible. So I ACK it.
>
> I'd like to test it a bit first with my fullmac card before it gets
> committed/added... But it's great to get some movement on this
> card/driver!
So my prism54 fullmac card appears to be broken, since it refuses to
associate with anything at all, even unencrypted access points. It
doesn't throw any errors at all, and it appears to be operating
correctly other than not associating.
Is there any way to get more information out of the firmware about what
it's doing?
Dan
> Dan
>
> > Luis
> > -
> > To unsubscribe from this list: send the line "unsubscribe netdev" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at http://vger.kernel.org/majordomo-info.html
>
> -
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
2006-11-03 14:49 ` Dan Williams
@ 2006-11-03 16:06 ` Luis R. Rodriguez
2006-11-03 18:12 ` chunkeey
0 siblings, 1 reply; 39+ messages in thread
From: Luis R. Rodriguez @ 2006-11-03 16:06 UTC (permalink / raw)
To: Dan Williams; +Cc: chunkeey@web.de, John W. Linville, netdev
On 11/3/06, Dan Williams <dcbw@redhat.com> wrote:
> On Tue, 2006-10-31 at 11:05 -0500, Dan Williams wrote:
> > On Mon, 2006-10-30 at 15:17 -0500, Luis R. Rodriguez wrote:
> > > On 10/29/06, chunkeey@web.de <chunkeey@web.de> wrote:
> > > > This patch completes WPA/RSN with TKIP support for all fullmac prism54 cards.
> > > > I removed all parts which are not relevant for wpa_supplicant (managed mode).
> > >
> > > This is great effort and thanks for it! My only concern with the patch
> > > is breaking compatiblity with 2.4 but then again I'm tired of having
> > > to keep this compat work up too and soon, after d80211 full force push
> > > it may not be possible. So I ACK it.
> >
> > I'd like to test it a bit first with my fullmac card before it gets
> > committed/added... But it's great to get some movement on this
> > card/driver!
>
> So my prism54 fullmac card appears to be broken, since it refuses to
> associate with anything at all, even unencrypted access points. It
> doesn't throw any errors at all, and it appears to be operating
> correctly other than not associating.
chunkeey, I figured your patch was well tested as you had it sitting
there for a while I gotta find a fullmac working card (most of them
broke while debugging) to debug.
> Is there any way to get more information out of the firmware about what
> it's doing?
The driver supports prism54_get_oid and prism54_set_u32. The list of
OIDs available are on isl_oid.h on oid_num_t enum. Just an FYI you if
you need to access the *EX OIDs you just need to be in extended mode.
Also for WPA you need to be in extended mode. To say the least last
the driver was pretty unstable in extended mode last I used worked on
it. Dan do you get any funky mgt timeouts on your ring buffer?
Anything useful there?
Luis
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
2006-11-03 16:06 ` Luis R. Rodriguez
@ 2006-11-03 18:12 ` chunkeey
2006-11-03 18:41 ` Luis R. Rodriguez
0 siblings, 1 reply; 39+ messages in thread
From: chunkeey @ 2006-11-03 18:12 UTC (permalink / raw)
To: Luis R. Rodriguez; +Cc: netdev, Dan Williams
[-- Attachment #1: Type: text/plain, Size: 2334 bytes --]
Am Freitag, 3. November 2006 17:06 schrieben Sie:
> On 11/3/06, Dan Williams <dcbw@redhat.com> wrote:
> > On Tue, 2006-10-31 at 11:05 -0500, Dan Williams wrote:
> > > On Mon, 2006-10-30 at 15:17 -0500, Luis R. Rodriguez wrote:
> > > > On 10/29/06, chunkeey@web.de <chunkeey@web.de> wrote:
> > > > > This patch completes WPA/RSN with TKIP support for all fullmac
> > > > > prism54 cards. I removed all parts which are not relevant for
> > > > > wpa_supplicant (managed mode).
> > > >
> > > > This is great effort and thanks for it! My only concern with the
> > > > patch is breaking compatiblity with 2.4 but then again I'm tired of
> > > > having to keep this compat work up too and soon, after d80211 full
> > > > force push it may not be possible. So I ACK it.
> > >
> > > I'd like to test it a bit first with my fullmac card before it gets
> > > committed/added... But it's great to get some movement on this
> > > card/driver!
> >
> > So my prism54 fullmac card appears to be broken, since it refuses to
> > associate with anything at all, even unencrypted access points. It
> > doesn't throw any errors at all, and it appears to be operating
> > correctly other than not associating.
>
> chunkeey, I figured your patch was well tested as you had it sitting
> there for a while I gotta find a fullmac working card (most of them
> broke while debugging) to debug.
>
well, it was already tested by:
Maxi, Dan S., Gabriel, C and "me".
"The best configuration is: WPA2 with TKIP!"
> > Is there any way to get more information out of the firmware about what
> > it's doing?
>
> The driver supports prism54_get_oid and prism54_set_u32. The list of
> OIDs available are on isl_oid.h on oid_num_t enum. Just an FYI you if
> you need to access the *EX OIDs you just need to be in extended mode.
> Also for WPA you need to be in extended mode. To say the least last
> the driver was pretty unstable in extended mode last I used worked on
> it. Dan do you get any funky mgt timeouts on your ring buffer?
> Anything useful there?
>
> Luis
yes, especially mgt_commit_list caused alot headaches, until I removed
DOT11_OID_PSM from the cache list.
Now, I can "hammer" it with ping -f for hours.
OT: I don't know if my last mail made it to the mailing-list. I haven't
seen it on the inet archieves, so here's a "resend".
Christian
[-- Attachment #2: prism-wpa-wl26git4.patch --]
[-- Type: text/x-diff, Size: 77204 bytes --]
diff --git a/drivers/net/wireless/prism54/isl_38xx.c b/drivers/net/wireless/prism54/isl_38xx.c
index 02fc67b..044a23f 100644
--- a/drivers/net/wireless/prism54/isl_38xx.c
+++ b/drivers/net/wireless/prism54/isl_38xx.c
@@ -24,7 +24,6 @@ #include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/io.h>
-#include "prismcompat.h"
#include "isl_38xx.h"
#include "islpci_dev.h"
#include "islpci_mgt.h"
diff --git a/drivers/net/wireless/prism54/isl_38xx.h b/drivers/net/wireless/prism54/isl_38xx.h
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 4a20e45..126a85e 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -3,6 +3,7 @@
* (C) 2003,2004 Aurelien Alleaume <slts@free.fr>
* (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
* (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
+ * (C) 2006 Christian Lamparter <chunkeey@web.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,18 +27,13 @@ #include <linux/pci.h>
#include <asm/uaccess.h>
-#include "prismcompat.h"
#include "isl_ioctl.h"
#include "islpci_mgt.h"
#include "isl_oid.h" /* additional types and defs for isl38xx fw */
#include "oid_mgt.h"
#include <net/iw_handler.h> /* New driver API */
-
-#define KEY_SIZE_WEP104 13 /* 104/128-bit WEP keys */
-#define KEY_SIZE_WEP40 5 /* 40/64-bit WEP keys */
-/* KEY_SIZE_TKIP should match isl_oid.h, struct obj_key.key[] size */
-#define KEY_SIZE_TKIP 32 /* TKIP keys */
+#include <net/ieee80211.h>
static void prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid,
u8 *wpa_ie, size_t wpa_ie_len);
@@ -45,11 +41,6 @@ static size_t prism54_wpa_bss_ie_get(isl
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
@@ -167,14 +158,16 @@ prism54_update_stats(islpci_private *pri
if (down_interruptible(&priv->stats_sem))
return;
-/* Noise floor.
- * I'm not sure if the unit is dBm.
- * Note : If we are not connected, this value seems to be irrelevant. */
+ /* Noise floor.
+ * I'm not sure if the unit is dBm.
+
+ * Note :
+ * If we are not connected, this value seems to be irrelevant. */
mgt_get_request(priv, DOT11_OID_NOISEFLOOR, 0, NULL, &r);
priv->local_iwstatistics.qual.noise = r.u;
-/* Get the rssi of the link. To do this we need to retrieve a bss. */
+ /* Get the rssi of the link. To do this we need to retrieve a bss. */
/* First get the MAC address of the AP we are associated with. */
mgt_get_request(priv, DOT11_OID_BSSID, 0, NULL, &r);
@@ -199,11 +192,11 @@ prism54_update_stats(islpci_private *pri
/* report that the stats are new */
priv->local_iwstatistics.qual.updated = 0x7;
-/* Rx : unable to decrypt the MPDU */
+ /* Rx : unable to decrypt the MPDU */
mgt_get_request(priv, DOT11_OID_PRIVRXFAILED, 0, NULL, &r);
priv->local_iwstatistics.discard.code = r.u;
-/* Tx : Max MAC retries num reached */
+ /* Tx : Max MAC retries num reached */
mgt_get_request(priv, DOT11_OID_MPDUTXFAILED, 0, NULL, &r);
priv->local_iwstatistics.discard.retries = r.u;
@@ -227,7 +220,7 @@ prism54_get_wireless_stats(struct net_de
} else
priv->iwstatistics.qual.updated = 0;
- /* Update our wireless stats, but do not schedule to often
+ /* Update our wireless stats, but do not schedule too often
* (max 1 HZ) */
if ((priv->stats_timestamp == 0) ||
time_after(jiffies, priv->stats_timestamp + 1 * HZ)) {
@@ -414,6 +407,8 @@ prism54_get_sens(struct net_device *ndev
return rvalue;
}
+#define WEP40_KEY_LEN 5 /* 40/64-bit WEP keys */
+
static int
prism54_get_range(struct net_device *ndev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
@@ -435,11 +430,11 @@ prism54_get_range(struct net_device *nde
/* Now the encoding capabilities */
range->num_encoding_sizes = 3;
/* 64(40) bits WEP */
- range->encoding_size[0] = 5;
+ range->encoding_size[0] = WEP40_KEY_LEN;
/* 128(104) bits WEP */
- range->encoding_size[1] = 13;
+ range->encoding_size[1] = WEP_KEY_LEN;
/* 256 bits for WPA-PSK */
- range->encoding_size[2] = 32;
+ range->encoding_size[2] = SCM_KEY_LEN;
/* 4 keys are allowed */
range->max_encoding_tokens = 4;
@@ -565,6 +560,11 @@ prism54_set_scan(struct net_device *dev,
return 0;
}
+/* In 500 kbps */
+static const unsigned char scan_rate_list[] = { 2, 4, 11, 22,
+ 12, 18, 24, 36,
+ 48, 72, 96, 108 };
+
/* a little helper that will translate our data into a card independent
* format that the Wireless Tools will understand. This was inspired by
* the "Aironet driver for 4500 and 4800 series cards" (GPL)
@@ -596,17 +596,12 @@ prism54_translate_bss(struct net_device
current_ev = iwe_stream_add_point(current_ev, end_buf,
&iwe, bss->ssid.octets);
- /* Capabilities */
-#define CAP_ESS 0x01
-#define CAP_IBSS 0x02
-#define CAP_CRYPT 0x10
-
/* Mode */
cap = bss->capinfo;
iwe.u.mode = 0;
- if (cap & CAP_ESS)
+ if (cap & WLAN_CAPABILITY_ESS)
iwe.u.mode = IW_MODE_MASTER;
- else if (cap & CAP_IBSS)
+ else if (cap & WLAN_CAPABILITY_IBSS)
iwe.u.mode = IW_MODE_ADHOC;
iwe.cmd = SIOCGIWMODE;
if (iwe.u.mode)
@@ -615,7 +610,7 @@ #define CAP_CRYPT 0x10
IW_EV_UINT_LEN);
/* Encryption capability */
- if (cap & CAP_CRYPT)
+ if (cap & WLAN_CAPABILITY_PRIVACY)
iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
@@ -875,15 +870,6 @@ prism54_set_rate(struct net_device *ndev
data[1] = 0;
}
-/*
- i = 0;
- printk("prism54 rate: ");
- while(data[i]) {
- printk("%u ", data[i]);
- i++;
- }
- printk("0\n");
-*/
profile = -1;
ret = mgt_set_request(priv, DOT11_OID_PROFILES, 0, &profile);
ret |= mgt_set_request(priv, DOT11_OID_EXTENDEDRATES, 0, data);
@@ -1052,18 +1038,58 @@ prism54_get_retry(struct net_device *nde
}
static int
+prism54_set_auth_alg(islpci_private *priv, u32 flag)
+{
+ int authen = DOT11_AUTH_NONE, invoke = 0, exunencrypt = 0;
+ int ret;
+
+ if (flag & IW_ENCODE_RESTRICTED) {
+ authen = DOT11_AUTH_SK;
+ invoke = 1;
+ exunencrypt = 1;
+ }
+
+ if (flag & IW_ENCODE_OPEN) {
+ authen = DOT11_AUTH_OS;
+ invoke = 1;
+ /*
+ This is very wrong here, but we've to ensure bug-to-bug compatibility.
+
+ If we set exunencrypt, the Firmware adds the "Privacy" flag to the
+ Capability Information, which is misreaded by many STA/AP as
+ "the device supports WEP, WPA and WPA2"
+ */
+ exunencrypt = 1;
+ }
+
+ ret =
+ mgt_set_request(priv, DOT11_OID_AUTHENABLE,
+ 0, &authen);
+ ret |=
+ mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED,
+ 0, &invoke);
+ ret |=
+ mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED,
+ 0,&exunencrypt);
+
+ return ret;
+}
+
+static int
prism54_set_encode(struct net_device *ndev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
- int rvalue = 0, force = 0;
- int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0;
+ int rvalue = 0, flags = dwrq->flags;
union oid_res_t r;
/* with the new API, it's impossible to get a NULL pointer.
* New version of iwconfig set the IW_ENCODE_NOKEY flag
* when no key is given, but older versions don't. */
+ if (islpci_get_state(priv) < PRV_STATE_INIT)
+ return -EINVAL;
+
if (dwrq->length > 0) {
/* we have a key to set */
int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
@@ -1071,27 +1097,27 @@ prism54_set_encode(struct net_device *nd
struct obj_key key = { DOT11_PRIV_WEP, 0, "" };
/* get the current key index */
- rvalue = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
+ rvalue |= mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
current_index = r.u;
/* Verify that the key is not marked as invalid */
if (!(dwrq->flags & IW_ENCODE_NOKEY)) {
- if (dwrq->length > KEY_SIZE_TKIP) {
+ if (dwrq->length > MAX_KEY_LEN) {
/* User-provided key data too big */
return -EINVAL;
}
- if (dwrq->length > KEY_SIZE_WEP104) {
+ if (dwrq->length > WEP_KEY_LEN) {
/* WPA-PSK TKIP */
key.type = DOT11_PRIV_TKIP;
- key.length = KEY_SIZE_TKIP;
- } else if (dwrq->length > KEY_SIZE_WEP40) {
+ key.length = MAX_KEY_LEN;
+ } else if (dwrq->length > WEP40_KEY_LEN) {
/* WEP 104/128 */
- key.length = KEY_SIZE_WEP104;
+ key.length = WEP_KEY_LEN;
} else {
/* WEP 40/64 */
- key.length = KEY_SIZE_WEP40;
+ key.length = WEP40_KEY_LEN;
}
memset(key.key, 0, sizeof (key.key));
- memcpy(key.key, extra, dwrq->length);
+ memcpy(key.key, extra, key.length);
if ((index < 0) || (index > 3))
/* no index provided use the current one */
@@ -1108,95 +1134,111 @@ prism54_set_encode(struct net_device *nd
* This is also how "iwconfig ethX key on" works
*/
if ((index == current_index) && (key.length > 0))
- force = 1;
+ flags |= IW_ENCODE_RESTRICTED;
} else {
- int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
+ int index = (flags & IW_ENCODE_INDEX) - 1;
if ((index >= 0) && (index <= 3)) {
/* we want to set the key index */
rvalue |=
mgt_set_request(priv, DOT11_OID_DEFKEYID, 0,
&index);
} else {
- if (!dwrq->flags & IW_ENCODE_MODE) {
+ if (!(flags & IW_ENCODE_MODE)) {
/* we cannot do anything. Complain. */
return -EINVAL;
}
}
}
- /* now read the flags */
- if (dwrq->flags & IW_ENCODE_DISABLED) {
- /* Encoding disabled,
- * authen = DOT11_AUTH_OS;
- * invoke = 0;
- * exunencrypt = 0; */
- }
- if (dwrq->flags & IW_ENCODE_OPEN)
- /* Encode but accept non-encoded packets. No auth */
- invoke = 1;
- if ((dwrq->flags & IW_ENCODE_RESTRICTED) || force) {
- /* Refuse non-encoded packets. Auth */
- authen = DOT11_AUTH_BOTH;
- invoke = 1;
- exunencrypt = 1;
- }
/* do the change if requested */
- if ((dwrq->flags & IW_ENCODE_MODE) || force) {
- rvalue |=
- mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
- rvalue |=
- mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &invoke);
- rvalue |=
- mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0,
- &exunencrypt);
- }
+ if (flags & IW_ENCODE_MODE)
+ rvalue = prism54_set_auth_alg(priv, flags);
+
return rvalue;
}
static int
+prism54_get_auth_algs(islpci_private *priv)
+{
+ u32 authen = 0, invoke = 0, exunencrypt = 0;
+ union oid_res_t r;
+ int ret = 0;
+
+ ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
+ authen = r.u;
+ ret |= mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
+ invoke = r.u;
+ ret |= mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
+ exunencrypt = r.u;
+
+ if (ret)
+ return ret;
+
+ if (invoke && exunencrypt &&
+ ((authen == DOT11_AUTH_SK) || (authen == DOT11_AUTH_BOTH)))
+ ret = IW_ENCODE_RESTRICTED | IW_ENCODE_ENABLED;
+ else if ((authen == DOT11_AUTH_OS)) {
+ if (invoke)
+ ret = IW_ENCODE_OPEN | IW_ENCODE_ENABLED;
+ else {
+ ret = IW_ENCODE_DISABLED;
+ }
+ }
+ else {
+ ret = IW_ENCODE_DISABLED;
+ }
+
+ return ret;
+}
+
+static int
prism54_get_encode(struct net_device *ndev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
struct obj_key *key;
u32 devindex, index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
- u32 authen = 0, invoke = 0, exunencrypt = 0;
- int rvalue;
+ int rvalue = 0, flags;
union oid_res_t r;
+ if (islpci_get_state(priv) < PRV_STATE_INIT) {
+ dwrq->flags = IW_ENCODE_DISABLED;
+ dwrq->length = 0;
+ return 0;
+ }
+
/* first get the flags */
- rvalue = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
- authen = r.u;
- rvalue |= mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
- invoke = r.u;
- rvalue |= mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
- exunencrypt = r.u;
+ if ((flags = prism54_get_auth_algs(priv)) < 0)
+ return rvalue;
- if (invoke && (authen == DOT11_AUTH_BOTH) && exunencrypt)
- dwrq->flags = IW_ENCODE_RESTRICTED;
- else if ((authen == DOT11_AUTH_OS) && !exunencrypt) {
- if (invoke)
- dwrq->flags = IW_ENCODE_OPEN;
- else
- dwrq->flags = IW_ENCODE_DISABLED;
- } else
- /* The card should not work in this state */
- dwrq->flags = 0;
+ memset(extra, 0x0, dwrq->length);
+ dwrq->flags = flags;
- /* get the current device key index */
- 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))
- /* no index provided, use the current one */
- index = devindex;
- rvalue |= mgt_get_request(priv, DOT11_OID_DEFKEYX, index, NULL, &r);
- key = r.ptr;
- dwrq->length = key->length;
- memcpy(extra, key->key, dwrq->length);
- kfree(key);
- /* return the used key index */
- dwrq->flags |= devindex + 1;
+ if (flags != IW_ENCODE_DISABLED) {
+ /* get the current device key index */
+ 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))
+ /* no index provided, use the current one */
+ index = devindex;
+
+ rvalue |= mgt_get_request(priv, DOT11_OID_DEFKEYX, index, NULL, &r);
+ key = r.ptr;
+
+ if (dwrq->length < key->length) {
+ kfree(key);
+ return -EINVAL;
+ }
+
+ dwrq->length = key->length;
+ memcpy(extra, key->key, dwrq->length);
+ kfree(key);
+ /* return the used key index */
+ dwrq->flags |= devindex + 1;
+ } else
+ rvalue = 0;
+
return rvalue;
}
@@ -1212,7 +1254,7 @@ prism54_get_txpower(struct net_device *n
/* intersil firmware operates in 0.25 dBm (1/4 dBm) */
vwrq->value = (s32) r.u / 4;
vwrq->fixed = 1;
- /* radio is not turned of
+ /* radio is not turned off
* btw: how is possible to turn off only the radio
*/
vwrq->disabled = 0;
@@ -1246,9 +1288,9 @@ prism54_set_txpower(struct net_device *n
}
}
-static int prism54_set_genie(struct net_device *ndev,
- struct iw_request_info *info,
- struct iw_point *data, char *extra)
+static int
+prism54_set_genie(struct net_device *ndev, struct iw_request_info *info,
+ struct iw_point *data, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
int alen, ret = 0;
@@ -1258,6 +1300,9 @@ static int prism54_set_genie(struct net_
(data->length && extra == NULL))
return -EINVAL;
+ if (islpci_get_state(priv) < PRV_STATE_INIT)
+ return -EINVAL;
+
memcpy(priv->wpa_ie, extra, data->length);
priv->wpa_ie_len = data->length;
@@ -1266,28 +1311,26 @@ static int prism54_set_genie(struct net_
if (attach == NULL)
return -ENOMEM;
-#define WLAN_FC_TYPE_MGMT 0
-#define WLAN_FC_STYPE_ASSOC_REQ 0
-#define WLAN_FC_STYPE_REASSOC_REQ 2
-
/* Note: endianness is covered by mgt_set_varlen */
- attach->type = (WLAN_FC_TYPE_MGMT << 2) |
- (WLAN_FC_STYPE_ASSOC_REQ << 4);
- attach->id = -1;
- attach->size = priv->wpa_ie_len;
- memcpy(attach->data, extra, priv->wpa_ie_len);
-
- ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach,
- priv->wpa_ie_len);
- if (ret == 0) {
- attach->type = (WLAN_FC_TYPE_MGMT << 2) |
- (WLAN_FC_STYPE_REASSOC_REQ << 4);
-
- ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach,
- priv->wpa_ie_len);
- if (ret == 0)
- printk(KERN_DEBUG "%s: WPA IE Attachment was set\n",
- ndev->name);
+ attach->id = -1; // global IE
+ attach->size = data->length;
+ memcpy(attach->data, extra, data->length);
+
+ if (priv->iw_mode == IW_MODE_MASTER) {
+ attach->type = IEEE80211_STYPE_BEACON;
+ ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT,
+ attach, data->length);
+ attach->type = IEEE80211_STYPE_PROBE_RESP;
+ ret |= mgt_set_varlen(priv, DOT11_OID_ATTACHMENT,
+ attach, data->length);
+ }
+ else {
+ attach->type = IEEE80211_STYPE_ASSOC_REQ;
+ ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT,
+ attach, data->length);
+ attach->type = IEEE80211_STYPE_REASSOC_REQ;
+ ret |= mgt_set_varlen(priv, DOT11_OID_ATTACHMENT,
+ attach, data->length);
}
kfree(attach);
@@ -1295,9 +1338,9 @@ #define WLAN_FC_STYPE_REASSOC_REQ 2
}
-static int prism54_get_genie(struct net_device *ndev,
- struct iw_request_info *info,
- struct iw_point *data, char *extra)
+static int
+prism54_get_genie(struct net_device *ndev, struct iw_request_info *info,
+ struct iw_point *data, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
int len = priv->wpa_ie_len;
@@ -1316,38 +1359,17 @@ static int prism54_get_genie(struct net_
return 0;
}
-static int prism54_set_auth(struct net_device *ndev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
+static int
+prism54_set_auth(struct net_device *ndev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
struct iw_param *param = &wrqu->param;
- u32 mlmelevel = 0, authen = 0, dot1x = 0;
- u32 exunencrypt = 0, privinvoked = 0, wpa = 0;
- u32 old_wpa;
- int ret = 0;
- union oid_res_t r;
+ u32 set = 0;
+ int rvalue = 0;
if (islpci_get_state(priv) < PRV_STATE_INIT)
- return 0;
-
- /* first get the flags */
- down_write(&priv->mib_sem);
- wpa = old_wpa = priv->wpa;
- up_write(&priv->mib_sem);
- ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
- authen = r.u;
- ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
- privinvoked = r.u;
- ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
- exunencrypt = r.u;
- ret = mgt_get_request(priv, DOT11_OID_DOT1XENABLE, 0, NULL, &r);
- dot1x = r.u;
- ret = mgt_get_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, NULL, &r);
- mlmelevel = r.u;
-
- if (ret < 0)
- goto out;
+ return -EINVAL;
switch (param->flags & IW_AUTH_INDEX) {
case IW_AUTH_CIPHER_PAIRWISE:
@@ -1355,103 +1377,72 @@ static int prism54_set_auth(struct net_d
case IW_AUTH_KEY_MGMT:
break;
- case IW_AUTH_WPA_ENABLED:
- /* Do the same thing as IW_AUTH_WPA_VERSION */
- if (param->value) {
- wpa = 1;
- privinvoked = 1; /* For privacy invoked */
- exunencrypt = 1; /* Filter out all unencrypted frames */
- dot1x = 0x01; /* To enable eap filter */
- mlmelevel = DOT11_MLME_EXTENDED;
- authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
- } else {
- wpa = 0;
- privinvoked = 0;
- exunencrypt = 0; /* Do not filter un-encrypted data */
- dot1x = 0;
- mlmelevel = DOT11_MLME_AUTO;
- }
- break;
-
case IW_AUTH_WPA_VERSION:
- if (param->value & IW_AUTH_WPA_VERSION_DISABLED) {
- wpa = 0;
- privinvoked = 0;
- exunencrypt = 0; /* Do not filter un-encrypted data */
- dot1x = 0;
- mlmelevel = DOT11_MLME_AUTO;
- } else {
- if (param->value & IW_AUTH_WPA_VERSION_WPA)
- wpa = 1;
- else if (param->value & IW_AUTH_WPA_VERSION_WPA2)
- wpa = 2;
- privinvoked = 1; /* For privacy invoked */
- exunencrypt = 1; /* Filter out all unencrypted frames */
- dot1x = 0x01; /* To enable eap filter */
- mlmelevel = DOT11_MLME_EXTENDED;
- authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
- }
+ if (set & IW_AUTH_WPA_VERSION_WPA)
+ set = 1;
+ if (set & IW_AUTH_WPA_VERSION_WPA2)
+ set |= 2;
+ case IW_AUTH_WPA_ENABLED:
+ if (!set)
+ set = param->value ? 3 : 0;
+ rvalue = prism54_set_wpa(ndev, info, &set, extra);
break;
case IW_AUTH_RX_UNENCRYPTED_EAPOL:
- dot1x = param->value ? 1 : 0;
+ set = param->value ? 1 : 0;
+ rvalue = mgt_set_request(priv, DOT11_OID_DOT1XENABLE,
+ 0, &set);
break;
case IW_AUTH_PRIVACY_INVOKED:
- privinvoked = param->value ? 1 : 0;
+ set = param->value ? 1 : 0;
+ rvalue = mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED,
+ 0, &set);
+ break;
case IW_AUTH_DROP_UNENCRYPTED:
- exunencrypt = param->value ? 1 : 0;
+ set = param->value ? 1 : 0;
+ rvalue = mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED,
+ 0, &set);
break;
case IW_AUTH_80211_AUTH_ALG:
- if (param->value & IW_AUTH_ALG_SHARED_KEY) {
- /* Only WEP uses _SK and _BOTH */
- if (wpa > 0) {
- ret = -EINVAL;
- goto out;
- }
- authen = DOT11_AUTH_SK;
- } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
- authen = DOT11_AUTH_OS;
- } else {
- ret = -EINVAL;
- goto out;
+ switch (param->value) {
+ case IW_AUTH_ALG_OPEN_SYSTEM:
+ set = DOT11_AUTH_OS;
+ break;
+ case IW_AUTH_ALG_SHARED_KEY:
+ set = DOT11_AUTH_SK;
+ break;
+ default:
+ return -EINVAL;
+ break;
}
+ rvalue = mgt_set_request(priv, DOT11_OID_AUTHENABLE,
+ 0, &set);
break;
default:
- return -EOPNOTSUPP;
+ rvalue = -EOPNOTSUPP;
+ break;
}
- /* Set all the values */
- down_write(&priv->mib_sem);
- priv->wpa = wpa;
- up_write(&priv->mib_sem);
- mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
- mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &privinvoked);
- mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0, &exunencrypt);
- mgt_set_request(priv, DOT11_OID_DOT1XENABLE, 0, &dot1x);
- mgt_set_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, &mlmelevel);
-
-out:
- return ret;
+ return rvalue;
}
-static int prism54_get_auth(struct net_device *ndev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
+static int
+prism54_get_auth(struct net_device *ndev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
struct iw_param *param = &wrqu->param;
- u32 wpa = 0;
- int ret = 0;
union oid_res_t r;
+ u32 wpa = 0;
+ int rvalue = 0;
if (islpci_get_state(priv) < PRV_STATE_INIT)
return 0;
- /* first get the flags */
down_write(&priv->mib_sem);
wpa = priv->wpa;
up_write(&priv->mib_sem);
@@ -1463,272 +1454,292 @@ static int prism54_get_auth(struct net_d
/*
* wpa_supplicant will control these internally
*/
- ret = -EOPNOTSUPP;
- break;
+ param->value = 0;
+ return -EOPNOTSUPP;
+ break;
case IW_AUTH_WPA_VERSION:
- switch (wpa) {
- case 1:
- param->value = IW_AUTH_WPA_VERSION_WPA;
- break;
- case 2:
- param->value = IW_AUTH_WPA_VERSION_WPA2;
- break;
- case 0:
- default:
+ if (!wpa)
param->value = IW_AUTH_WPA_VERSION_DISABLED;
- break;
- }
+ if (wpa & 1)
+ param->value = IW_AUTH_WPA_VERSION_WPA;
+ if (wpa & 2)
+ param->value |= IW_AUTH_WPA_VERSION_WPA2;
+
break;
case IW_AUTH_DROP_UNENCRYPTED:
- ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
- if (ret >= 0)
- param->value = r.u > 0 ? 1 : 0;
+ rvalue = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED,
+ 0, NULL, &r);
+ param->value = r.u;
break;
case IW_AUTH_80211_AUTH_ALG:
- ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
- if (ret >= 0) {
- switch (r.u) {
- case DOT11_AUTH_OS:
- param->value = IW_AUTH_ALG_OPEN_SYSTEM;
- break;
- case DOT11_AUTH_BOTH:
- case DOT11_AUTH_SK:
- param->value = IW_AUTH_ALG_SHARED_KEY;
- case DOT11_AUTH_NONE:
- default:
- param->value = 0;
- break;
- }
+ rvalue = mgt_get_request(priv, DOT11_OID_AUTHENABLE,
+ 0, NULL, &r);
+
+ switch (r.u) {
+ case DOT11_AUTH_OS:
+ param->value = IW_AUTH_ALG_OPEN_SYSTEM;
+ break;
+ case DOT11_AUTH_BOTH:
+ case DOT11_AUTH_SK:
+ param->value = IW_AUTH_ALG_SHARED_KEY;
+ break;
+ default:
+ param->value = 0;
+ rvalue = -EOPNOTSUPP;
+ break;
}
break;
case IW_AUTH_WPA_ENABLED:
- param->value = wpa > 0 ? 1 : 0;
+ param->value = wpa ? 0 : 1;
break;
case IW_AUTH_RX_UNENCRYPTED_EAPOL:
- ret = mgt_get_request(priv, DOT11_OID_DOT1XENABLE, 0, NULL, &r);
- if (ret >= 0)
- param->value = r.u > 0 ? 1 : 0;
+ rvalue = mgt_get_request(priv, DOT11_OID_DOT1XENABLE,
+ 0, NULL, &r);
+ param->value = r.u;
break;
case IW_AUTH_PRIVACY_INVOKED:
- ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
- if (ret >= 0)
- param->value = r.u > 0 ? 1 : 0;
+ rvalue = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED,
+ 0, NULL, &r);
+ param->value = r.u;
break;
default:
return -EOPNOTSUPP;
+ break;
}
- return ret;
+
+ return 0;
}
-static int prism54_set_encodeext(struct net_device *ndev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+static int
+prism54_set_encodeext(struct net_device *ndev, struct iw_request_info *info,
+ struct iw_point *dwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
- struct iw_point *encoding = &wrqu->encoding;
- struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- int idx, alg = ext->alg, set_key = 1;
+ struct iw_encode_ext *enc = (struct iw_encode_ext *)extra;
+ struct obj_stakey* key;
union oid_res_t r;
- int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0;
- int ret = 0;
-
- if (islpci_get_state(priv) < PRV_STATE_INIT)
- return 0;
-
- /* Determine and validate the key index */
- idx = (encoding->flags & IW_ENCODE_INDEX) - 1;
- if (idx) {
- if (idx < 0 || idx > 3)
- return -EINVAL;
- } else {
- ret = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
- if (ret < 0)
- goto out;
- idx = r.u;
- }
+ int index, key_type, keyop = DOT11_KEYOP_SET_KEY;
+ int ret = -EINVAL;
- if (encoding->flags & IW_ENCODE_DISABLED)
- alg = IW_ENCODE_ALG_NONE;
-
- if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
- /* Only set transmit key index here, actual
- * key is set below if needed.
- */
- ret = mgt_set_request(priv, DOT11_OID_DEFKEYID, 0, &idx);
- set_key = ext->key_len > 0 ? 1 : 0;
- }
+ if ((islpci_get_state(priv) < PRV_STATE_INIT) ||
+ (enc->key_len > (dwrq->length - sizeof(*enc))) ||
+ (enc->addr.sa_family != ARPHRD_ETHER))
+ return -EINVAL;
- if (set_key) {
- struct obj_key key = { DOT11_PRIV_WEP, 0, "" };
- switch (alg) {
+ switch (enc->alg) {
case IW_ENCODE_ALG_NONE:
+#if 0
+ key_type = DOT11_PRIV_WEP;
+ keyop = DOT11_KEYOP_REMOVE_KEY;
+#else
+ return 0;
+#endif
break;
case IW_ENCODE_ALG_WEP:
- if (ext->key_len > KEY_SIZE_WEP104) {
- ret = -EINVAL;
- goto out;
- }
- if (ext->key_len > KEY_SIZE_WEP40)
- key.length = KEY_SIZE_WEP104;
- else
- key.length = KEY_SIZE_WEP40;
+ key_type = DOT11_PRIV_WEP;
break;
case IW_ENCODE_ALG_TKIP:
- if (ext->key_len > KEY_SIZE_TKIP) {
- ret = -EINVAL;
- goto out;
- }
- key.type = DOT11_PRIV_TKIP;
- key.length = KEY_SIZE_TKIP;
+ key_type = DOT11_PRIV_TKIP;
+ break;
default:
- return -EINVAL;
- }
-
- if (key.length) {
- memset(key.key, 0, sizeof(key.key));
- memcpy(key.key, ext->key, ext->key_len);
- ret = mgt_set_request(priv, DOT11_OID_DEFKEYX, idx,
- &key);
- if (ret < 0)
- goto out;
- }
+ return -EOPNOTSUPP;
}
- /* Read the flags */
- if (encoding->flags & IW_ENCODE_DISABLED) {
- /* Encoding disabled,
- * authen = DOT11_AUTH_OS;
- * invoke = 0;
- * exunencrypt = 0; */
- }
- if (encoding->flags & IW_ENCODE_OPEN) {
- /* Encode but accept non-encoded packets. No auth */
- invoke = 1;
- }
- if (encoding->flags & IW_ENCODE_RESTRICTED) {
- /* Refuse non-encoded packets. Auth */
- authen = DOT11_AUTH_BOTH;
- invoke = 1;
- exunencrypt = 1;
+ index = (dwrq->flags & IW_ENCODE_INDEX);
+ if ((index < 0) || (index > 3)) {
+ /* no index provided, so get the current one */
+ ret = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
+ if (ret)
+ return ret;
+ index = r.u;
}
- /* do the change if requested */
- if (encoding->flags & IW_ENCODE_MODE) {
- ret = mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0,
- &authen);
- ret = mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0,
- &invoke);
- ret = mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0,
- &exunencrypt);
+ key = kzalloc(sizeof(*key) + enc->key_len, GFP_KERNEL);
+ if (!key)
+ return -ENOMEM;
+
+ key->type = key_type;
+ key->length = enc->key_len;
+ key->keyid = index;
+ key->reserved = keyop;
+ if (!(enc->ext_flags & IW_ENCODE_EXT_GROUP_KEY))
+ key->options = DOT11_STAKEY_OPTION_DEFAULTKEY;
+ else
+ key->options = DOT11_STAKEY_OPTION_GROUPKEY;
+
+ memcpy(key->key, enc->key, key->length);
+ memcpy(key->address, enc->addr.sa_data, ETH_ALEN);
+
+ ret = mgt_set_request(priv, DOT11_OID_STAKEY, 0, key);
+ kfree(key);
+ if (ret)
+ return ret;
+
+ if (enc->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
+ struct obj_stasc *stasc;
+ stasc = kzalloc(sizeof(*stasc), GFP_KERNEL);
+ if (!stasc)
+ return -ENOMEM;
+ memcpy(stasc->address, enc->addr.sa_data, ETH_ALEN);
+ stasc->keyid = index;
+ stasc->tx_sc = 1;
+ memcpy(stasc->sc, enc->rx_seq, 6);
+ ret = mgt_set_request(priv, DOT11_OID_STASC, 0, stasc);
+ kfree(stasc);
+ if (ret)
+ return ret;
}
-out:
+ if (dwrq->flags & IW_ENCODE_MODE)
+ ret = prism54_set_auth_alg(priv, dwrq->flags);
+
return ret;
}
-
-static int prism54_get_encodeext(struct net_device *ndev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+static int
+prism54_get_encodeext(struct net_device *ndev,
+ struct iw_request_info *info, struct iw_point *dwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
- struct iw_point *encoding = &wrqu->encoding;
- struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- int idx, max_key_len;
+ struct iw_encode_ext *enc = (struct iw_encode_ext *)extra;
+ struct obj_stasc *stasc;
union oid_res_t r;
- int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0, wpa = 0;
- int ret = 0;
+ int index;
+ int ret = -EINVAL;
+ int max_key_len;
- if (islpci_get_state(priv) < PRV_STATE_INIT)
- return 0;
-
- /* first get the flags */
- ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
- authen = r.u;
- ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
- invoke = r.u;
- ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
- exunencrypt = r.u;
- if (ret < 0)
- goto out;
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
- max_key_len = encoding->length - sizeof(*ext);
+ max_key_len = dwrq->length - sizeof(*enc);
if (max_key_len < 0)
return -EINVAL;
- idx = (encoding->flags & IW_ENCODE_INDEX) - 1;
- if (idx) {
- if (idx < 0 || idx > 3)
- return -EINVAL;
- } else {
+ memset(enc, 0, sizeof(*enc));
+
+ if (islpci_get_state(priv) < PRV_STATE_INIT) {
+ dwrq->flags = IW_ENCODE_DISABLED;
+ return 0;
+ }
+
+ index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
+ if ((index < 0) || (index > 3)) {
+ /* no index provided, so get the current one */
ret = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
- if (ret < 0)
- goto out;
- idx = r.u;
+ if (ret)
+ return ret;
+ index = r.u;
}
- encoding->flags = idx + 1;
- memset(ext, 0, sizeof(*ext));
+ if (enc->addr.sa_family != ARPHRD_ETHER) {
+ /* no "per-station key" */
+ struct obj_key *key;
+ ret = mgt_get_request(priv, DOT11_OID_DEFKEYX, index, NULL, &r);
+ key = r.ptr;
+ if (ret) {
+ kfree(key);
+ return ret;
+ }
- switch (authen) {
- case DOT11_AUTH_BOTH:
- case DOT11_AUTH_SK:
- wrqu->encoding.flags |= IW_ENCODE_RESTRICTED;
- case DOT11_AUTH_OS:
- default:
- wrqu->encoding.flags |= IW_ENCODE_OPEN;
+ if (key->length > max_key_len) {
+ kfree(key);
+ return -E2BIG;
+ }
+
+ enc->key_len = key->length;
+ switch (key->type) {
+ case DOT11_PRIV_WEP:
+ enc->alg = IW_ENCODE_ALG_WEP;
+ break;
+ case DOT11_PRIV_TKIP:
+ enc->alg = IW_ENCODE_ALG_TKIP;
break;
- }
+ default:
+ kfree(key);
+ return -EIO;
+ break;
+ }
- down_write(&priv->mib_sem);
- wpa = priv->wpa;
- up_write(&priv->mib_sem);
+ dwrq->flags |= IW_ENCODE_ENABLED;
+ memcpy(enc->key, key->key, enc->key_len);
+ dwrq->flags |= index +1;
+ return ret;
- if (authen == DOT11_AUTH_OS && !exunencrypt && !invoke && !wpa) {
- /* No encryption */
- ext->alg = IW_ENCODE_ALG_NONE;
- ext->key_len = 0;
- wrqu->encoding.flags |= IW_ENCODE_DISABLED;
- } else {
- struct obj_key *key;
+ }
+ else {
+ /* no "per-station key" */
+ struct obj_stakey *key;
+ key = kzalloc(sizeof(*key), GFP_KERNEL);
+ if (!key)
+ return -ENOMEM;
+
+ memcpy(key->address, enc->addr.sa_data, ETH_ALEN);
+ key->keyid = index;
+ ret = mgt_get_request(priv, DOT11_OID_STAKEY, 0, (void*)key, &r);
+ kfree(key);
+ key = (struct obj_stakey*)r.ptr;
+ if (ret) {
+ kfree(key);
+ return ret;
+ }
- ret = mgt_get_request(priv, DOT11_OID_DEFKEYX, idx, NULL, &r);
- if (ret < 0)
- goto out;
- key = r.ptr;
- if (max_key_len < key->length) {
- ret = -E2BIG;
- goto out;
+ if (key->length > max_key_len) {
+ kfree(key);
+ return -EINVAL;
}
- memcpy(ext->key, key->key, key->length);
- ext->key_len = key->length;
switch (key->type) {
- case DOT11_PRIV_TKIP:
- ext->alg = IW_ENCODE_ALG_TKIP;
+ case DOT11_PRIV_WEP:
+ enc->alg = IW_ENCODE_ALG_WEP;
break;
- default:
- case DOT11_PRIV_WEP:
- ext->alg = IW_ENCODE_ALG_WEP;
+ case DOT11_PRIV_TKIP:
+ enc->alg = IW_ENCODE_ALG_TKIP;
+ break;
+ default:
+ kfree(key);
+ return -EIO;
break;
}
- wrqu->encoding.flags |= IW_ENCODE_ENABLED;
+
+ enc->key_len = key->length;
+ dwrq->flags = index + 1;
+ memcpy(enc->key, key->key, key->length);
+ kfree(key);
+
+ /* add replay counter */
+ stasc = kzalloc(sizeof(*stasc), GFP_KERNEL);
+ if (!stasc)
+ return -ENOMEM;
+
+ memcpy(stasc->address, enc->addr.sa_data, ETH_ALEN);
+ stasc->keyid = index;
+ stasc->tx_sc = 1;
+ ret = mgt_get_request(priv, DOT11_OID_STASC, 0, (void*)stasc, &r);
+ kfree(stasc);
+ stasc = (struct obj_stasc*)r.ptr;
+ if (ret) {
+ kfree(stasc);
+ return ret;
+ }
+
+ memset(enc->tx_seq, 0, IW_ENCODE_SEQ_MAX_SIZE);
+ // prism's FW has only a 6 byte wide RSC!
+ memcpy(enc->tx_seq, stasc->sc, IW_ENCODE_SEQ_MAX_SIZE - 2);
+ enc->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID;
+ kfree(stasc);
+
}
-out:
return ret;
}
-
static int
prism54_reset(struct net_device *ndev, struct iw_request_info *info,
__u32 * uwrq, char *extra)
@@ -2030,14 +2041,12 @@ 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 " MAC_FMT " [%2.2x %2.2X %4.4X]",
str,
((priv->iw_mode == IW_MODE_MASTER) ? "from" : "to"),
- a[0], a[1], a[2], a[3], a[4], a[5],
- (error ? (mlme->code ? " : REJECTED " : " : ACCEPTED ")
- : ""), mlme->code);
+ MAC_ARG(mlme->address),
+ mlme->state, mlme->code, mlme->id);
BUG_ON(n > IW_CUSTOM_MAX);
*length = n;
}
@@ -2103,12 +2112,6 @@ struct ieee80211_beacon_phdr {
u16 capab_info;
} __attribute__ ((packed));
-#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)
@@ -2140,10 +2143,9 @@ prism54_wpa_bss_ie_add(islpci_private *p
struct islpci_bss_wpa_ie, list);
list_del(&bss->list);
} else {
- bss = kmalloc(sizeof (*bss), GFP_ATOMIC);
+ bss = kzalloc(sizeof(*bss), GFP_ATOMIC);
if (bss != NULL) {
priv->num_bss_wpa++;
- memset(bss, 0, sizeof (*bss));
}
}
if (bss != NULL) {
@@ -2157,8 +2159,8 @@ prism54_wpa_bss_ie_add(islpci_private *p
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 " MAC_FMT
+ "\n", MAC_ARG(bssid));
}
/* expire old entries from WPA list */
@@ -2220,6 +2222,8 @@ prism54_wpa_bss_ie_clean(islpci_private
}
}
+static u8 wpa_oid[4] = { 0x00, 0x50, 0xf2, 1 };
+
static void
prism54_process_bss_data(islpci_private *priv, u32 oid, u8 *addr,
u8 *payload, size_t len)
@@ -2235,11 +2239,16 @@ prism54_process_bss_data(islpci_private
end = payload + len;
while (pos < end) {
if (pos + 2 + pos[1] > end) {
- printk(KERN_DEBUG "Parsing Beacon/ProbeResp failed "
- "for " MACSTR "\n", MAC2STR(addr));
+ printk(KERN_DEBUG "Parsing %s failed "
+ "for " MAC_FMT "\n", (oid == DOT11_OID_BEACON ? "Beacon" : "ProbeResp"), MAC_ARG(addr));
return;
}
- if (pos[0] == WLAN_EID_GENERIC && pos[1] >= 4 &&
+ /* Don't forget RSN/WPA2 ! */
+ if (pos[0] == MFIE_TYPE_RSN && pos[1] > 4) {
+ prism54_wpa_bss_ie_add(priv, addr, pos, pos[1] + 2);
+ return;
+ }
+ if (pos[0] == MFIE_TYPE_GENERIC && pos[1] >= 4 &&
memcmp(pos + 2, wpa_oid, 4) == 0) {
prism54_wpa_bss_ie_add(priv, addr, pos, pos[1] + 2);
return;
@@ -2264,39 +2273,81 @@ handle_request(islpci_private *priv, str
}
static int
+prism54_process_sta_trap(islpci_private *priv, enum oid_num_t oid,
+ struct obj_mlmeex* mlmeex)
+{
+ struct obj_mlme *mlme = (struct obj_mlme*)mlmeex;
+ int ret = 0;
+
+ switch (oid) {
+ case DOT11_OID_DEAUTHENTICATEEX:
+ send_formatted_event(priv, "DeAuthenticate request",
+ mlme, 0);
+ break;
+
+ case DOT11_OID_AUTHENTICATEEX:
+ if (prism54_mac_accept(&priv->acl, mlmeex->address) &&
+ (mlmeex->state == DOT11_STATE_AUTH)) {
+
+ mlmeex->state = DOT11_STATE_ASSOCING;
+ mlmeex->code = 0;
+ mlmeex->size = 0;
+ ret = mgt_set_request(priv, DOT11_OID_ASSOCIATEEX,
+ 0, mlmeex);
+ if (ret)
+ return ret;
+ }
+ if (mlmeex->code != 0)
+ send_formatted_event(priv, "Authenticate request",
+ mlme, 1);
+ break;
+
+ case DOT11_OID_DISASSOCIATEEX:
+ send_formatted_event(priv, "Disassociate request",
+ mlme, 0);
+ break;
+
+ case DOT11_OID_ASSOCIATEEX:
+ if (mlmeex->code)
+ send_formatted_event(priv, "Associate request",
+ mlme, 1);
+ break;
+
+ case DOT11_OID_REASSOCIATEEX:
+ if (mlmeex->code)
+ send_formatted_event(priv, "Reassociate request",
+ mlme, 1);
+ break;
+
+ default:
+ printk(KERN_INFO "%s: Unhandled OID %x, "
+ "please fill a bug-report!\n", priv->ndev->name, oid);
+ break;
+ }
+
+ return ret;
+}
+
+static int
prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
char *data)
{
struct obj_mlme *mlme = (struct obj_mlme *) data;
struct obj_mlmeex *mlmeex = (struct obj_mlmeex *) data;
- struct obj_mlmeex *confirm;
- u8 wpa_ie[MAX_WPA_IE_LEN];
- int wpa_ie_len;
- size_t len = 0; /* u16, better? */
- u8 *payload = NULL, *pos = NULL;
- int ret;
-
- /* I think all trapable objects are listed here.
- * Some oids have a EX version. The difference is that they are emitted
- * in DOT11_MLME_EXTENDED mode (set with DOT11_OID_MLMEAUTOLEVEL)
- * with more info.
- * The few events already defined by the wireless tools are not really
- * suited. We use the more flexible custom event facility.
- */
-
- if (oid >= DOT11_OID_BEACON) {
- len = mlmeex->size;
- payload = pos = mlmeex->data;
- }
+ int ret = 0;
/* I fear prism54_process_bss_data won't work with big endian data */
- if ((oid == DOT11_OID_BEACON) || (oid == DOT11_OID_PROBE))
- prism54_process_bss_data(priv, oid, mlmeex->address,
- payload, len);
mgt_le_to_cpu(isl_oid[oid].flags & OID_FLAG_TYPE, (void *) mlme);
switch (oid) {
+ case DOT11_OID_BEACON:
+ case DOT11_OID_PROBE:
+ if (priv->iw_mode != IW_MODE_MASTER
+ && mlmeex->state != DOT11_STATE_AUTHING)
+ prism54_process_bss_data(priv, oid, mlmeex->address,
+ mlmeex->data, mlmeex->size);
+ break;
case GEN_OID_LINKSTATE:
link_changed(priv->ndev, (u32) *data);
@@ -2329,163 +2380,12 @@ prism54_process_trap_helper(islpci_priva
send_formatted_event(priv, "ReAssociate request", mlme, 1);
break;
- case DOT11_OID_BEACON:
- send_formatted_event(priv,
- "Received a beacon from an unkown AP",
- mlme, 0);
- break;
-
- case DOT11_OID_PROBE:
- /* we received a probe from a client. */
- send_formatted_event(priv, "Received a probe from client", mlme,
- 0);
- break;
-
- /* Note : "mlme" is actually a "struct obj_mlmeex *" here, but this
- * is backward compatible layout-wise with "struct obj_mlme".
- */
-
- case DOT11_OID_DEAUTHENTICATEEX:
- send_formatted_event(priv, "DeAuthenticate request", mlme, 0);
- break;
-
- case DOT11_OID_AUTHENTICATEEX:
- handle_request(priv, mlme, oid);
- send_formatted_event(priv, "Authenticate request (ex)", mlme, 1);
-
- if (priv->iw_mode != IW_MODE_MASTER
- && mlmeex->state != DOT11_STATE_AUTHING)
- break;
-
- confirm = kmalloc(sizeof(struct obj_mlmeex) + 6, GFP_ATOMIC);
-
- 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]
- );
- confirm->id = -1; /* or mlmeex->id ? */
- confirm->state = 0; /* not used */
- confirm->code = 0;
- confirm->size = 6;
- confirm->data[0] = 0x00;
- confirm->data[1] = 0x00;
- confirm->data[2] = 0x02;
- confirm->data[3] = 0x00;
- confirm->data[4] = 0x00;
- confirm->data[5] = 0x00;
-
- ret = mgt_set_varlen(priv, DOT11_OID_ASSOCIATEEX, confirm, 6);
-
- kfree(confirm);
- if (ret)
- return ret;
- break;
-
- case DOT11_OID_DISASSOCIATEEX:
- send_formatted_event(priv, "Disassociate request (ex)", mlme, 0);
- break;
-
- case DOT11_OID_ASSOCIATEEX:
- handle_request(priv, mlme, oid);
- send_formatted_event(priv, "Associate request (ex)", mlme, 1);
-
- if (priv->iw_mode != IW_MODE_MASTER
- && mlmeex->state != DOT11_STATE_ASSOCING)
- break;
-
- confirm = kmalloc(sizeof(struct obj_mlmeex), GFP_ATOMIC);
-
- if (!confirm)
- break;
-
- memcpy(&confirm->address, mlmeex->address, ETH_ALEN);
-
- confirm->id = ((struct obj_mlmeex *)mlme)->id;
- confirm->state = 0; /* not used */
- confirm->code = 0;
-
- 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]
- );
- kfree(confirm);
- break;
- }
-
- 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;
-
- 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
- && mlmeex->state != DOT11_STATE_ASSOCING)
- break;
-
- confirm = kmalloc(sizeof(struct obj_mlmeex), GFP_ATOMIC);
-
- if (!confirm)
- break;
-
- memcpy(&confirm->address, mlmeex->address, ETH_ALEN);
-
- confirm->id = mlmeex->id;
- confirm->state = 0; /* not used */
- confirm->code = 0;
-
- 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]
- );
- kfree(confirm);
- break;
- }
-
- 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:
- return -EINVAL;
+ ret = prism54_process_sta_trap(priv, oid, mlmeex);
+ break;
}
- return 0;
+ return ret;
}
/*
@@ -2521,368 +2421,33 @@ prism54_set_mac_address(struct net_devic
return ret;
}
-/* Note: currently, use hostapd ioctl from the Host AP driver for WPA
- * support. This is to be replaced with Linux wireless extensions once they
- * get WPA support. */
-
-/* Note II: please leave all this together as it will be easier to remove later,
- * once wireless extensions add WPA support -mcgrof */
-
-/* PRISM54_HOSTAPD ioctl() cmd: */
-enum {
- PRISM2_SET_ENCRYPTION = 6,
- PRISM2_HOSTAPD_SET_GENERIC_ELEMENT = 12,
- PRISM2_HOSTAPD_MLME = 13,
- PRISM2_HOSTAPD_SCAN_REQ = 14,
-};
-
-#define PRISM54_SET_WPA SIOCIWFIRSTPRIV+12
-#define PRISM54_HOSTAPD SIOCIWFIRSTPRIV+25
-#define PRISM54_DROP_UNENCRYPTED SIOCIWFIRSTPRIV+26
-
-#define PRISM2_HOSTAPD_MAX_BUF_SIZE 1024
-#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)
- * used in ioctl() */
-#define HOSTAP_CRYPT_ALG_NAME_LEN 16
-
-struct prism2_hostapd_param {
- u32 cmd;
- u8 sta_addr[ETH_ALEN];
- union {
- struct {
- u8 alg[HOSTAP_CRYPT_ALG_NAME_LEN];
- u32 flags;
- u32 err;
- u8 idx;
- u8 seq[8]; /* sequence counter (set: RX, get: TX) */
- u16 key_len;
- u8 key[0];
- } crypt;
- struct {
- u8 len;
- u8 data[0];
- } generic_elem;
- struct {
-#define MLME_STA_DEAUTH 0
-#define MLME_STA_DISASSOC 1
- u16 cmd;
- u16 reason_code;
- } mlme;
- struct {
- u8 ssid_len;
- u8 ssid[32];
- } scan_req;
- } u;
-};
-
-
-static int
-prism2_ioctl_set_encryption(struct net_device *dev,
- struct prism2_hostapd_param *param,
- int param_len)
-{
- islpci_private *priv = netdev_priv(dev);
- int rvalue = 0, force = 0;
- int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0;
- union oid_res_t r;
-
- /* with the new API, it's impossible to get a NULL pointer.
- * New version of iwconfig set the IW_ENCODE_NOKEY flag
- * when no key is given, but older versions don't. */
-
- if (param->u.crypt.key_len > 0) {
- /* we have a key to set */
- int index = param->u.crypt.idx;
- int current_index;
- struct obj_key key = { DOT11_PRIV_TKIP, 0, "" };
-
- /* get the current key index */
- rvalue = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
- current_index = r.u;
- /* Verify that the key is not marked as invalid */
- if (!(param->u.crypt.flags & IW_ENCODE_NOKEY)) {
- key.length = param->u.crypt.key_len > sizeof (param->u.crypt.key) ?
- sizeof (param->u.crypt.key) : param->u.crypt.key_len;
- memcpy(key.key, param->u.crypt.key, key.length);
- if (key.length == 32)
- /* we want WPA-PSK */
- key.type = DOT11_PRIV_TKIP;
- if ((index < 0) || (index > 3))
- /* no index provided use the current one */
- index = current_index;
-
- /* now send the key to the card */
- rvalue |=
- mgt_set_request(priv, DOT11_OID_DEFKEYX, index,
- &key);
- }
- /*
- * 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
- */
- if ((index == current_index) && (key.length > 0))
- force = 1;
- } else {
- int index = (param->u.crypt.flags & IW_ENCODE_INDEX) - 1;
- if ((index >= 0) && (index <= 3)) {
- /* we want to set the key index */
- rvalue |=
- mgt_set_request(priv, DOT11_OID_DEFKEYID, 0,
- &index);
- } else {
- if (!param->u.crypt.flags & IW_ENCODE_MODE) {
- /* we cannot do anything. Complain. */
- return -EINVAL;
- }
- }
- }
- /* now read the flags */
- if (param->u.crypt.flags & IW_ENCODE_DISABLED) {
- /* Encoding disabled,
- * authen = DOT11_AUTH_OS;
- * invoke = 0;
- * exunencrypt = 0; */
- }
- if (param->u.crypt.flags & IW_ENCODE_OPEN)
- /* Encode but accept non-encoded packets. No auth */
- invoke = 1;
- if ((param->u.crypt.flags & IW_ENCODE_RESTRICTED) || force) {
- /* Refuse non-encoded packets. Auth */
- authen = DOT11_AUTH_BOTH;
- invoke = 1;
- exunencrypt = 1;
- }
- /* do the change if requested */
- if ((param->u.crypt.flags & IW_ENCODE_MODE) || force) {
- rvalue |=
- mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
- rvalue |=
- mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &invoke);
- rvalue |=
- mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0,
- &exunencrypt);
- }
- return rvalue;
-}
-
-static int
-prism2_ioctl_set_generic_element(struct net_device *ndev,
- struct prism2_hostapd_param *param,
- int param_len)
-{
- islpci_private *priv = netdev_priv(ndev);
- int max_len, len, alen, ret=0;
- struct obj_attachment *attach;
-
- len = param->u.generic_elem.len;
- max_len = param_len - PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN;
- if (max_len < 0 || max_len < len)
- return -EINVAL;
-
- alen = sizeof(*attach) + len;
- attach = kmalloc(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
-
- /* Note: endianness is covered by mgt_set_varlen */
-
- attach->type = (WLAN_FC_TYPE_MGMT << 2) |
- (WLAN_FC_STYPE_ASSOC_REQ << 4);
- attach->id = -1;
- attach->size = len;
- memcpy(attach->data, param->u.generic_elem.data, len);
-
- ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach, len);
-
- if (ret == 0) {
- attach->type = (WLAN_FC_TYPE_MGMT << 2) |
- (WLAN_FC_STYPE_REASSOC_REQ << 4);
-
- ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach, len);
-
- if (ret == 0)
- printk(KERN_DEBUG "%s: WPA IE Attachment was set\n",
- ndev->name);
- }
-
- kfree(attach);
- return ret;
-
-}
-
-static int
-prism2_ioctl_mlme(struct net_device *dev, struct prism2_hostapd_param *param)
-{
- return -EOPNOTSUPP;
-}
-
-static int
-prism2_ioctl_scan_req(struct net_device *ndev,
- struct prism2_hostapd_param *param)
-{
- islpci_private *priv = netdev_priv(ndev);
- int i, rvalue;
- struct obj_bsslist *bsslist;
- u32 noise = 0;
- char *extra = "";
- char *current_ev = "foo";
- union oid_res_t r;
-
- if (islpci_get_state(priv) < PRV_STATE_INIT) {
- /* device is not ready, fail gently */
- return 0;
- }
-
- /* first get the noise value. We will use it to report the link quality */
- rvalue = mgt_get_request(priv, DOT11_OID_NOISEFLOOR, 0, NULL, &r);
- noise = r.u;
-
- /* Ask the device for a list of known bss. We can report at most
- * IW_MAX_AP=64 to the range struct. 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 < min(IW_MAX_AP, (int) bsslist->nr); i++)
- current_ev = prism54_translate_bss(ndev, current_ev,
- extra + IW_SCAN_MAX_DATA,
- &(bsslist->bsslist[i]),
- noise);
- kfree(bsslist);
-
- return rvalue;
-}
-
-static int
-prism54_hostapd(struct net_device *ndev, struct iw_point *p)
-{
- struct prism2_hostapd_param *param;
- int ret = 0;
- u32 uwrq;
-
- printk(KERN_DEBUG "prism54_hostapd - len=%d\n", p->length);
- if (p->length < sizeof(struct prism2_hostapd_param) ||
- p->length > PRISM2_HOSTAPD_MAX_BUF_SIZE || !p->pointer)
- return -EINVAL;
-
- param = (struct prism2_hostapd_param *) kmalloc(p->length, GFP_KERNEL);
- if (param == NULL)
- return -ENOMEM;
-
- if (copy_from_user(param, p->pointer, p->length)) {
- kfree(param);
- return -EFAULT;
- }
-
- switch (param->cmd) {
- case PRISM2_SET_ENCRYPTION:
- printk(KERN_DEBUG "%s: Caught WPA supplicant set encryption request\n",
- ndev->name);
- ret = prism2_ioctl_set_encryption(ndev, param, p->length);
- break;
- case PRISM2_HOSTAPD_SET_GENERIC_ELEMENT:
- printk(KERN_DEBUG "%s: Caught WPA supplicant set WPA IE request\n",
- ndev->name);
- ret = prism2_ioctl_set_generic_element(ndev, param,
- p->length);
- break;
- case PRISM2_HOSTAPD_MLME:
- printk(KERN_DEBUG "%s: Caught WPA supplicant MLME request\n",
- ndev->name);
- ret = prism2_ioctl_mlme(ndev, param);
- break;
- case PRISM2_HOSTAPD_SCAN_REQ:
- printk(KERN_DEBUG "%s: Caught WPA supplicant scan request\n",
- ndev->name);
- ret = prism2_ioctl_scan_req(ndev, param);
- break;
- case PRISM54_SET_WPA:
- printk(KERN_DEBUG "%s: Caught WPA supplicant wpa init request\n",
- ndev->name);
- uwrq = 1;
- ret = prism54_set_wpa(ndev, NULL, &uwrq, NULL);
- break;
- case PRISM54_DROP_UNENCRYPTED:
- printk(KERN_DEBUG "%s: Caught WPA drop unencrypted request\n",
- ndev->name);
-#if 0
- uwrq = 0x01;
- mgt_set(priv, DOT11_OID_EXUNENCRYPTED, &uwrq);
- down_write(&priv->mib_sem);
- mgt_commit(priv);
- up_write(&priv->mib_sem);
-#endif
- /* Not necessary, as set_wpa does it, should we just do it here though? */
- ret = 0;
- break;
- default:
- printk(KERN_DEBUG "%s: Caught a WPA supplicant request that is not supported\n",
- ndev->name);
- ret = -EOPNOTSUPP;
- break;
- }
-
- if (ret == 0 && copy_to_user(p->pointer, param, p->length))
- ret = -EFAULT;
-
- kfree(param);
-
- return ret;
-}
-
static int
prism54_set_wpa(struct net_device *ndev, struct iw_request_info *info,
__u32 * uwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
- u32 mlme, authen, dot1x, filter, wep;
+ u32 mlme, dot1x;
if (islpci_get_state(priv) < PRV_STATE_INIT)
return 0;
- wep = 1; /* For privacy invoked */
- filter = 1; /* Filter out all unencrypted frames */
- dot1x = 0x01; /* To enable eap filter */
- mlme = DOT11_MLME_EXTENDED;
- authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
+ dot1x = 0; // disable global filtering
+ mlme = DOT11_MLME_AUTO;
down_write(&priv->mib_sem);
priv->wpa = *uwrq;
- switch (priv->wpa) {
- default:
- case 0: /* Clears/disables WPA and friends */
- wep = 0;
- filter = 0; /* Do not filter un-encrypted data */
- dot1x = 0;
- mlme = DOT11_MLME_AUTO;
- printk("%s: Disabling WPA\n", ndev->name);
- break;
- case 2:
- case 1: /* WPA */
- printk("%s: Enabling WPA\n", ndev->name);
- break;
+ if (priv->wpa) {
+ if (priv->iw_mode == IW_MODE_MASTER)
+ dot1x = 1;
+ mlme = DOT11_MLME_EXTENDED;
}
up_write(&priv->mib_sem);
- mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
- mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &wep);
- mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0, &filter);
mgt_set_request(priv, DOT11_OID_DOT1XENABLE, 0, &dot1x);
mgt_set_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, &mlme);
- return 0;
+ return prism54_set_auth_alg(priv, IW_ENCODE_OPEN);
}
static int
@@ -2890,7 +2455,9 @@ prism54_get_wpa(struct net_device *ndev,
__u32 * uwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
+ down_write(&priv->mib_sem);
*uwrq = priv->wpa;
+ up_write(&priv->mib_sem);
return 0;
}
@@ -3025,6 +2592,80 @@ prism54_set_spy(struct net_device *ndev,
return iw_handler_set_spy(ndev, info, uwrq, extra);
}
+static int
+prism54_send_mlme(struct net_device *ndev, struct iw_request_info *info,
+ struct iw_point *dwrq, char *extra)
+{
+ islpci_private *priv = netdev_priv(ndev);
+ struct iw_mlme *iwmlme;
+ struct obj_mlme mlme;
+ struct obj_sta *sta;
+ union oid_res_t r;
+ int ret = 0;
+
+ if (dwrq->length != sizeof(*iwmlme))
+ return -EINVAL;
+
+ iwmlme = (struct iw_mlme*)extra;
+
+ if (iwmlme->addr.sa_family != ARPHRD_ETHER)
+ return -EINVAL;
+
+ /* get STA/AP Id.
+ or the card will BROADCAST the packet! */
+
+ sta = (struct obj_sta*)kzalloc(sizeof(*sta), GFP_KERNEL);
+ if (!sta)
+ return -ENOMEM;
+
+ memcpy(sta->address, iwmlme->addr.sa_data, ETH_ALEN);
+ ret = mgt_get_request(priv, DOT11_OID_CLIENTFIND, 0, sta, &r);
+ kfree(sta);
+
+ if (ret) {
+ sta = r.ptr;
+ memcpy(mlme.address, iwmlme->addr.sa_data, ETH_ALEN);
+
+ if (sta->node >= 1)
+ mlme.id = sta->node;
+ else
+ mlme.id = -1;
+ } else
+ /* use broadcast id */
+ mlme.id = -1;
+
+ mlme.code = iwmlme->reason_code;
+
+ kfree(r.ptr);
+ switch (iwmlme->cmd) {
+ case IW_MLME_DEAUTH:
+ mlme.state = DOT11_STATE_NONE;
+ return mgt_set_request(priv, DOT11_OID_DEAUTHENTICATE,
+ 0, &mlme);
+ break;
+ case IW_MLME_DISASSOC:
+ mlme.state = DOT11_STATE_NONE;
+ return mgt_set_request(priv, DOT11_OID_DISASSOCIATE,
+ 0, &mlme);
+ break;
+#if 0
+ /* not in WEXT yet */
+ case IW_MLME_AUTH:
+ mlme.state = DOT11_STATE_AUTH;
+ return mgt_set_request(priv, DOT11_OID_AUTHENTICATE,
+ 0, &mlme);
+ break;
+ case IW_MLME_ASSOC:
+ mlme.state = DOT11_STATE_ASSOC;
+ return mgt_set_request(priv, DOT11_OID_ASSOCIATE,
+ 0, &mlme);
+ break;
+#endif
+ }
+
+ return -EOPNOTSUPP;
+}
+
static const iw_handler prism54_handler[] = {
(iw_handler) prism54_commit, /* SIOCSIWCOMMIT */
(iw_handler) prism54_get_name, /* SIOCGIWNAME */
@@ -3042,13 +2683,13 @@ static const iw_handler prism54_handler[
(iw_handler) NULL, /* SIOCGIWPRIV */
(iw_handler) NULL, /* SIOCSIWSTATS */
(iw_handler) NULL, /* SIOCGIWSTATS */
- prism54_set_spy, /* SIOCSIWSPY */
+ (iw_handler) prism54_set_spy, /* SIOCSIWSPY */
iw_handler_get_spy, /* SIOCGIWSPY */
iw_handler_set_thrspy, /* SIOCSIWTHRSPY */
iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
(iw_handler) prism54_set_wap, /* SIOCSIWAP */
(iw_handler) prism54_get_wap, /* SIOCGIWAP */
- (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) prism54_send_mlme, /* SIOCSIWMLME */
(iw_handler) NULL, /* SIOCGIWAPLIST depreciated */
(iw_handler) prism54_set_scan, /* SIOCSIWSCAN */
(iw_handler) prism54_get_scan, /* SIOCGIWSCAN */
@@ -3072,15 +2713,15 @@ static const iw_handler prism54_handler[
(iw_handler) prism54_get_encode, /* SIOCGIWENCODE */
(iw_handler) NULL, /* SIOCSIWPOWER */
(iw_handler) NULL, /* SIOCGIWPOWER */
- NULL, /* -- hole -- */
- NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
(iw_handler) prism54_set_genie, /* SIOCSIWGENIE */
(iw_handler) prism54_get_genie, /* SIOCGIWGENIE */
(iw_handler) prism54_set_auth, /* SIOCSIWAUTH */
(iw_handler) prism54_get_auth, /* SIOCGIWAUTH */
- (iw_handler) prism54_set_encodeext, /* SIOCSIWENCODEEXT */
- (iw_handler) prism54_get_encodeext, /* SIOCGIWENCODEEXT */
- NULL, /* SIOCSIWPMKSA */
+ (iw_handler) prism54_set_encodeext, /* SIOCSIWENCODEEXT */
+ (iw_handler) prism54_get_encodeext, /* SIOCGIWENCODEEXT */
+ (iw_handler) NULL /* SIOCSIWPMKSA */
};
/* The low order bit identify a SET (0) or a GET (1) ioctl. */
@@ -3259,14 +2900,5 @@ const struct iw_handler_def prism54_hand
int
prism54_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
{
- struct iwreq *wrq = (struct iwreq *) rq;
- int ret = -1;
- switch (cmd) {
- case PRISM54_HOSTAPD:
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- ret = prism54_hostapd(ndev, &wrq->u.data);
- return ret;
- }
return -EOPNOTSUPP;
}
diff --git a/drivers/net/wireless/prism54/isl_ioctl.h b/drivers/net/wireless/prism54/isl_ioctl.h
index e8183d3..8322133 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.h
+++ b/drivers/net/wireless/prism54/isl_ioctl.h
@@ -1,4 +1,5 @@
/*
+ *
* Copyright (C) 2002 Intersil Americas Inc.
* (C) 2003 Aurelien Alleaume <slts@free.fr>
* (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
@@ -21,12 +22,11 @@
#ifndef _ISL_IOCTL_H
#define _ISL_IOCTL_H
+#include <net/iw_handler.h> /* New driver API */
#include "islpci_mgt.h"
#include "islpci_dev.h"
-#include <net/iw_handler.h> /* New driver API */
-
-#define SUPPORTED_WIRELESS_EXT 19
+#define SUPPORTED_WIRELESS_EXT 21
void prism54_mib_init(islpci_private *);
diff --git a/drivers/net/wireless/prism54/isl_oid.h b/drivers/net/wireless/prism54/isl_oid.h
index b7534c2..88b24d6 100644
--- a/drivers/net/wireless/prism54/isl_oid.h
+++ b/drivers/net/wireless/prism54/isl_oid.h
@@ -2,6 +2,7 @@
* Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
* Copyright (C) 2004 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
* Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
+ * Copyright (C) 2006 Christian Lamparter <chunkeey@web.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,29 +27,67 @@ #define _ISL_OID_H
* with the device firmware
*/
+#define MAX_KEY_LEN 32
+
struct obj_ssid {
u8 length;
- char octets[33];
+ u8 octets[IW_ESSID_MAX_SIZE + 1];
} __attribute__ ((packed));
+enum dot11_priv_t {
+ DOT11_PRIV_WEP = 0,
+ DOT11_PRIV_TKIP = 1
+};
+
struct obj_key {
u8 type; /* dot11_priv_t */
u8 length;
- char key[32];
+ u8 key[MAX_KEY_LEN];
} __attribute__ ((packed));
+enum dot11_stakey_opt_t {
+ DOT11_STAKEY_OPTION_GROUPKEY = 0x0000,
+ DOT11_STAKEY_OPTION_DEFAULTKEY = 0x0001
+};
+
+enum dot11_keyop_t {
+ DOT11_KEYOP_SET_KEY = 0x0000,
+ DOT11_KEYOP_REMOVE_KEY = 0x0001
+};
+
+struct obj_stakey {
+ u8 address[ETH_ALEN];
+ u8 keyid;
+ u8 reserved; /* dot11_keyop_t */
+ u16 options; /* dot11_stakey_opt_t */
+ u8 type; /* dot11_priv_t */
+ u8 length;
+ u8 key[MAX_KEY_LEN];
+} __attribute__ ((packed));
+
+enum dot11_state_t {
+ DOT11_STATE_NONE = 0,
+ DOT11_STATE_AUTHING = 1,
+ DOT11_STATE_AUTH = 2,
+ DOT11_STATE_ASSOCING = 3,
+ DOT11_STATE_REASSOC = 4,
+ DOT11_STATE_ASSOC = 5,
+ DOT11_STATE_IBSS = 6,
+ DOT11_STATE_WDS = 7
+};
+
struct obj_mlme {
- u8 address[6];
+ u8 address[ETH_ALEN];
u16 id;
- u16 state;
- u16 code;
+ u16 state; /* dot11_state_t */
+ u16 code; /* WLAN_STATUS_ / WLAN_REASON_ */
} __attribute__ ((packed));
struct obj_mlmeex {
- u8 address[6];
+ u8 address[ETH_ALEN];
u16 id;
- u16 state;
- u16 code;
+ u16 state; /* dot11_state_t */
+ u16 code; /* WLAN_STATUS_ / WLAN_REASON_ */
u16 size;
u8 data[0];
} __attribute__ ((packed));
@@ -59,23 +98,23 @@ struct obj_buffer {
} __attribute__ ((packed));
struct obj_bss {
- u8 address[6];
+ u8 address[ETH_ALEN];
int:16; /* padding */
- char state;
- char reserved;
- short age;
+ u8 state; /* dot11_state_t */
+ u8 reserved;
+ u16 age;
- char quality;
- char rssi;
+ u8 quality;
+ u8 rssi;
struct obj_ssid ssid;
- short channel;
- char beacon_period;
- char dtim_period;
- short capinfo;
- short rates;
- short basic_rates;
+ u16 channel;
+ u8 beacon_period;
+ u8 dtim_period;
+ u16 capinfo; /* WLAN_CAPABILITY_ */
+ u16 rates;
+ u16 basic_rates;
int:16; /* padding */
} __attribute__ ((packed));
@@ -90,14 +129,33 @@ struct obj_frequencies {
} __attribute__ ((packed));
struct obj_attachment {
- char type;
- char reserved;
- short id;
- short size;
- char data[0];
+ u8 type; /* IEEE80211_STYPE_ */
+ u8 reserved;
+ u16 id;
+ u16 size;
+ u8 data[0];
} __attribute__((packed));
-/*
+struct obj_stasc {
+ u8 address[ETH_ALEN];
+ u8 keyid;
+ u8 tx_sc;
+ u8 sc[6];
+} __attribute__ ((packed));
+
+struct obj_sta {
+ u8 address[ETH_ALEN];
+ int:16;
+ u8 state; /* dot11_state_t */
+ u8 node; /* Station ID */
+ u16 age;
+ u8 reserved1;
+ u8 rssi;
+ u8 rate;
+ u8 reserved2;
+} __attribute__ ((packed));
+
+/*
* in case everything's ok, the inlined function below will be
* optimized away by the compiler...
*/
@@ -112,19 +170,12 @@ __bug_on_wrong_struct_sizes(void)
BUILD_BUG_ON(sizeof (struct obj_bss) != 60);
BUILD_BUG_ON(sizeof (struct obj_bsslist) != 4);
BUILD_BUG_ON(sizeof (struct obj_frequencies) != 2);
+ BUILD_BUG_ON(sizeof (struct obj_sta) != 16);
+ BUILD_BUG_ON(sizeof (struct obj_stasc) != 14);
+ BUILD_BUG_ON(sizeof (struct obj_stakey) != 44);
+ BUILD_BUG_ON(sizeof (struct obj_attachment) != 6);
}
-enum dot11_state_t {
- DOT11_STATE_NONE = 0,
- DOT11_STATE_AUTHING = 1,
- DOT11_STATE_AUTH = 2,
- DOT11_STATE_ASSOCING = 3,
-
- DOT11_STATE_ASSOC = 5,
- DOT11_STATE_IBSS = 6,
- DOT11_STATE_WDS = 7
-};
-
enum dot11_bsstype_t {
DOT11_BSSTYPE_NONE = 0,
DOT11_BSSTYPE_INFRA = 1,
@@ -145,11 +196,6 @@ enum dot11_mlme_t {
DOT11_MLME_EXTENDED = 2
};
-enum dot11_priv_t {
- DOT11_PRIV_WEP = 0,
- DOT11_PRIV_TKIP = 1
-};
-
/* Prism "Nitro" / Frameburst / "Packet Frame Grouping"
* Value is in microseconds. Represents the # microseconds
* the firmware will take to group frames before sending out then out
@@ -464,31 +510,32 @@ enum oid_num_t {
OID_NUM_LAST
};
-#define OID_FLAG_CACHED 0x80
-#define OID_FLAG_TYPE 0x7f
-
-#define OID_TYPE_U32 0x01
-#define OID_TYPE_SSID 0x02
-#define OID_TYPE_KEY 0x03
-#define OID_TYPE_BUFFER 0x04
-#define OID_TYPE_BSS 0x05
-#define OID_TYPE_BSSLIST 0x06
-#define OID_TYPE_FREQUENCIES 0x07
-#define OID_TYPE_MLME 0x08
-#define OID_TYPE_MLMEEX 0x09
-#define OID_TYPE_ADDR 0x0A
-#define OID_TYPE_RAW 0x0B
-#define OID_TYPE_ATTACH 0x0C
-
-/* OID_TYPE_MLMEEX is special because of a variable size field when sending.
- * Not yet implemented (not used in driver anyway).
- */
+enum oid_types_t {
+ OID_TYPE_U32 = 0x01,
+ OID_TYPE_SSID = 0x02,
+ OID_TYPE_KEY = 0x03,
+ OID_TYPE_BUFFER = 0x04,
+ OID_TYPE_BSS = 0x05,
+ OID_TYPE_BSSLIST = 0x06,
+ OID_TYPE_FREQUENCIES = 0x07,
+ OID_TYPE_MLME = 0x08,
+ OID_TYPE_MLMEEX = 0x09,
+ OID_TYPE_ADDR = 0x0A,
+ OID_TYPE_RAW = 0x0B,
+ OID_TYPE_ATTACH = 0x0C,
+ OID_TYPE_STASC = 0x0D,
+ OID_TYPE_STAKEY = 0x0E,
+ OID_TYPE_STAINFO = 0x0F,
+
+ OID_FLAG_CACHED = 0x80,
+ OID_FLAG_TYPE = 0x7f
+};
struct oid_t {
enum oid_num_t oid;
- short range; /* to define a range of oid */
- short size; /* max size of the associated data */
- char flags;
+ u16 range; /* to define a range of oid */
+ u16 size; /* max size of the associated data */
+ enum oid_types_t flags;
};
union oid_res_t {
@@ -496,8 +543,8 @@ union oid_res_t {
u32 u;
};
-#define IWMAX_BITRATES 20
-#define IWMAX_BSS 24
+#define IWMAX_BITRATES 20
+#define IWMAX_BSS 24
#define IWMAX_FREQ 30
#define PRIV_STR_SIZE 1024
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
index 1e0603c..e6d9b26 100644
--- a/drivers/net/wireless/prism54/islpci_dev.c
+++ b/drivers/net/wireless/prism54/islpci_dev.c
@@ -25,10 +25,10 @@ #include <linux/pci.h>
#include <linux/etherdevice.h>
#include <linux/delay.h>
#include <linux/if_arp.h>
+#include <linux/firmware.h>
#include <asm/io.h>
-#include "prismcompat.h"
#include "isl_38xx.h"
#include "isl_ioctl.h"
#include "islpci_dev.h"
@@ -86,7 +86,7 @@ isl_upload_firmware(islpci_private *priv
long fw_len;
const u32 *fw_ptr;
- rc = request_firmware(&fw_entry, priv->firmware, PRISM_FW_PDEV);
+ rc = request_firmware(&fw_entry, priv->firmware, &priv->pdev->dev);
if (rc) {
printk(KERN_ERR
"%s: request_firmware() failed for '%s'\n",
diff --git a/drivers/net/wireless/prism54/islpci_dev.h b/drivers/net/wireless/prism54/islpci_dev.h
index a9aa166..3d0bb8f 100644
--- a/drivers/net/wireless/prism54/islpci_dev.h
+++ b/drivers/net/wireless/prism54/islpci_dev.h
@@ -71,7 +71,6 @@ struct islpci_bss_wpa_ie {
u8 bssid[ETH_ALEN];
u8 wpa_ie[MAX_WPA_IE_LEN];
size_t wpa_ie_len;
-
};
typedef struct {
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
index 676d838..6da1f86 100644
--- a/drivers/net/wireless/prism54/islpci_eth.c
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -24,7 +24,6 @@ #include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
-#include "prismcompat.h"
#include "isl_38xx.h"
#include "islpci_eth.h"
#include "islpci_mgt.h"
@@ -482,8 +481,7 @@ #endif
void
islpci_do_reset_and_wake(void *data)
{
- islpci_private *priv = data;
-
+ islpci_private *priv = (islpci_private *) data;
islpci_reset(priv, 1);
priv->reset_task_pending = 0;
smp_wmb();
@@ -500,13 +498,12 @@ islpci_eth_tx_timeout(struct net_device
statistics->tx_errors++;
if (!priv->reset_task_pending) {
- printk(KERN_WARNING
- "%s: tx_timeout, scheduling reset", ndev->name);
+ printk(KERN_WARNING "%s: tx_timeout\n", ndev->name);
netif_stop_queue(ndev);
priv->reset_task_pending = 1;
schedule_work(&priv->reset_task);
} else {
printk(KERN_WARNING
- "%s: tx_timeout, waiting for reset", ndev->name);
+ "%s: tx_timeout, waiting for reset\n", ndev->name);
}
}
diff --git a/drivers/net/wireless/prism54/islpci_eth.h b/drivers/net/wireless/prism54/islpci_eth.h
diff --git a/drivers/net/wireless/prism54/islpci_hotplug.c b/drivers/net/wireless/prism54/islpci_hotplug.c
index f6354b1..0e07c2b 100644
--- a/drivers/net/wireless/prism54/islpci_hotplug.c
+++ b/drivers/net/wireless/prism54/islpci_hotplug.c
@@ -23,7 +23,6 @@ #include <linux/delay.h>
#include <linux/init.h> /* For __init, __exit */
#include <linux/dma-mapping.h>
-#include "prismcompat.h"
#include "islpci_dev.h"
#include "islpci_mgt.h" /* for pc_debug */
#include "isl_oid.h"
@@ -170,7 +169,8 @@ #endif
pci_set_master(pdev);
/* enable MWI */
- pci_set_mwi(pdev);
+ if (pci_set_mwi(pdev))
+ printk(KERN_ERR "%s: pci_set_mwi failed\n", DRV_NAME);
/* setup the network device interface and its structure */
if (!(ndev = islpci_setup(pdev))) {
@@ -289,7 +289,10 @@ prism54_resume(struct pci_dev *pdev)
islpci_private *priv = ndev ? netdev_priv(ndev) : NULL;
BUG_ON(!priv);
- pci_enable_device(pdev);
+ if (pci_enable_device(pdev)) {
+ printk(KERN_ERR "%s: pci_enable_device() failed.\n", DRV_NAME);
+ return -ENODEV;
+ }
printk(KERN_NOTICE "%s: got resume request\n", ndev->name);
diff --git a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c
index 036a875..8fd781d 100644
--- a/drivers/net/wireless/prism54/islpci_mgt.c
+++ b/drivers/net/wireless/prism54/islpci_mgt.c
@@ -25,7 +25,6 @@ #include <asm/io.h>
#include <asm/system.h>
#include <linux/if_arp.h>
-#include "prismcompat.h"
#include "isl_38xx.h"
#include "islpci_mgt.h"
#include "isl_oid.h" /* additional types and defs for isl38xx fw */
diff --git a/drivers/net/wireless/prism54/islpci_mgt.h b/drivers/net/wireless/prism54/islpci_mgt.h
diff --git a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c
index fbc52b6..24b5a49 100644
--- a/drivers/net/wireless/prism54/oid_mgt.c
+++ b/drivers/net/wireless/prism54/oid_mgt.c
@@ -16,7 +16,6 @@
*
*/
-#include "prismcompat.h"
#include "islpci_dev.h"
#include "islpci_mgt.h"
#include "isl_oid.h"
@@ -85,9 +84,9 @@ struct oid_t isl_oid[] = {
OID_U32_C(DOT11_OID_DEFKEYID, 0x12000003),
[DOT11_OID_DEFKEYX] = {0x12000004, 3, sizeof (struct obj_key),
OID_FLAG_CACHED | OID_TYPE_KEY}, /* DOT11_OID_DEFKEY1,...DOT11_OID_DEFKEY4 */
- OID_UNKNOWN(DOT11_OID_STAKEY, 0x12000008),
+ OID_STRUCT(DOT11_OID_STAKEY, 0x12000008, struct obj_stakey, OID_TYPE_STAKEY),
OID_U32(DOT11_OID_REKEYTHRESHOLD, 0x12000009),
- OID_UNKNOWN(DOT11_OID_STASC, 0x1200000a),
+ OID_STRUCT(DOT11_OID_STASC, 0x1200000a, struct obj_stasc, OID_TYPE_STASC),
OID_U32(DOT11_OID_PRIVTXREJECTED, 0x1a000000),
OID_U32(DOT11_OID_PRIVRXPLAIN, 0x1a000001),
@@ -122,9 +121,10 @@ struct oid_t isl_oid[] = {
OID_U32(DOT11_OID_BRIDGELOCAL, 0x15000000),
OID_U32(DOT11_OID_CLIENTS, 0x15000001),
OID_U32(DOT11_OID_CLIENTSASSOCIATED, 0x15000002),
- [DOT11_OID_CLIENTX] = {0x15000003, 2006, 0, 0}, /* DOT11_OID_CLIENTX,...DOT11_OID_CLIENT2007 */
+ [DOT11_OID_CLIENTX] = {0x15000003, 2006, sizeof(struct obj_sta),
+ OID_TYPE_STAINFO}, /* DOT11_OID_CLIENTX,...DOT11_OID_CLIENT2007 */
- OID_STRUCT(DOT11_OID_CLIENTFIND, 0x150007DB, u8[6], OID_TYPE_ADDR),
+ OID_STRUCT(DOT11_OID_CLIENTFIND, 0x150007DB, struct obj_sta, OID_TYPE_STAINFO),
OID_STRUCT(DOT11_OID_WDSLINKADD, 0x150007DC, u8[6], OID_TYPE_ADDR),
OID_STRUCT(DOT11_OID_WDSLINKREMOVE, 0x150007DD, u8[6], OID_TYPE_ADDR),
OID_STRUCT(DOT11_OID_EAPAUTHSTA, 0x150007DE, u8[6], OID_TYPE_ADDR),
@@ -201,8 +201,7 @@ struct oid_t isl_oid[] = {
OID_U32(DOT11_OID_STATIMEOUT, 0x19000000),
OID_U32_C(DOT11_OID_MLMEAUTOLEVEL, 0x19000001),
OID_U32(DOT11_OID_BSSTIMEOUT, 0x19000002),
- [DOT11_OID_ATTACHMENT] = {0x19000003, 0,
- sizeof(struct obj_attachment), OID_TYPE_ATTACH},
+ OID_STRUCT_C(DOT11_OID_ATTACHMENT, 0x19000003, sizeof(struct obj_attachment), OID_TYPE_ATTACH),
OID_STRUCT_C(DOT11_OID_PSMBUFFER, 0x19000004, struct obj_buffer,
OID_TYPE_BUFFER),
@@ -277,7 +276,7 @@ mgt_clean(islpci_private *priv)
}
void
-mgt_le_to_cpu(int type, void *data)
+mgt_le_to_cpu(enum oid_types_t type, void *data)
{
switch (type) {
case OID_TYPE_U32:
@@ -334,19 +333,31 @@ mgt_le_to_cpu(int type, void *data)
attach->id = le16_to_cpu(attach->id);
attach->size = le16_to_cpu(attach->size);
break;
- }
+ }
+ case OID_TYPE_STAKEY: {
+ struct obj_stakey *stakey = data;
+ stakey->options = le16_to_cpu(stakey->options);
+ break;
+ }
+ case OID_TYPE_STAINFO: {
+ struct obj_sta *sta = data;
+ sta->age = le16_to_cpu(sta->age);
+ break;
+ }
case OID_TYPE_SSID:
case OID_TYPE_KEY:
case OID_TYPE_ADDR:
case OID_TYPE_RAW:
+ case OID_TYPE_STASC:
break;
default:
BUG();
+ break;
}
}
static void
-mgt_cpu_to_le(int type, void *data)
+mgt_cpu_to_le(enum oid_types_t type, void *data)
{
switch (type) {
case OID_TYPE_U32:
@@ -403,14 +414,26 @@ mgt_cpu_to_le(int type, void *data)
attach->id = cpu_to_le16(attach->id);
attach->size = cpu_to_le16(attach->size);
break;
- }
+ }
+ case OID_TYPE_STAKEY: {
+ struct obj_stakey *stakey = data;
+ stakey->options = cpu_to_le16(stakey->options);
+ break;
+ }
+ case OID_TYPE_STAINFO: {
+ struct obj_sta *sta = data;
+ sta->age = cpu_to_le16(sta->age);
+ break;
+ }
case OID_TYPE_SSID:
case OID_TYPE_KEY:
case OID_TYPE_ADDR:
case OID_TYPE_RAW:
+ case OID_TYPE_STASC:
break;
default:
BUG();
+ break;
}
}
@@ -658,13 +681,16 @@ static enum oid_num_t commit_part1[] = {
static enum oid_num_t commit_part2[] = {
DOT11_OID_SSID,
+ /* problematic with WPA
DOT11_OID_PSMBUFFER,
+ */
DOT11_OID_AUTHENABLE,
DOT11_OID_PRIVACYINVOKED,
DOT11_OID_EXUNENCRYPTED,
DOT11_OID_DEFKEYX, /* MULTIPLE */
DOT11_OID_DEFKEYID,
DOT11_OID_DOT1XENABLE,
+ DOT11_OID_ATTACHMENT,
OID_INL_DOT11D_CONFORMANCE,
/* Do not initialize this - fw < 1.0.4.3 rejects it
OID_INL_OUTPUTPOWER,
diff --git a/drivers/net/wireless/prism54/oid_mgt.h b/drivers/net/wireless/prism54/oid_mgt.h
index 92c8a2d..10a5cc3 100644
--- a/drivers/net/wireless/prism54/oid_mgt.h
+++ b/drivers/net/wireless/prism54/oid_mgt.h
@@ -32,7 +32,7 @@ void mgt_clean(islpci_private *);
extern const int frequency_list_a[];
int channel_of_freq(int);
-void mgt_le_to_cpu(int, void *);
+void mgt_le_to_cpu(enum oid_types_t, void *);
int mgt_set_request(islpci_private *, enum oid_num_t, int, void *);
int mgt_set_varlen(islpci_private *, enum oid_num_t, void *, int);
diff --git a/drivers/net/wireless/prism54/prismcompat.h b/drivers/net/wireless/prism54/prismcompat.h
deleted file mode 100644
index aa1d174..0000000
--- a/drivers/net/wireless/prism54/prismcompat.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * (C) 2004 Margit Schubert-While <margitsw@t-online.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/*
- * Compatibility header file to aid support of different kernel versions
- */
-
-#ifdef PRISM54_COMPAT24
-#include "prismcompat24.h"
-#else /* PRISM54_COMPAT24 */
-
-#ifndef _PRISM_COMPAT_H
-#define _PRISM_COMPAT_H
-
-#include <linux/device.h>
-#include <linux/firmware.h>
-#include <linux/moduleparam.h>
-#include <linux/workqueue.h>
-#include <linux/compiler.h>
-
-#ifndef __iomem
-#define __iomem
-#endif
-
-#define PRISM_FW_PDEV &priv->pdev->dev
-
-#endif /* _PRISM_COMPAT_H */
-#endif /* PRISM54_COMPAT24 */
diff --git a/scripts/package/Makefile b/scripts/package/Makefile
diff --git a/scripts/package/builddeb b/scripts/package/builddeb
diff --git a/scripts/package/buildtar b/scripts/package/buildtar
diff --git a/scripts/package/mkspec b/scripts/package/mkspec
^ permalink raw reply related [flat|nested] 39+ messages in thread
* Re: [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
2006-11-03 18:12 ` chunkeey
@ 2006-11-03 18:41 ` Luis R. Rodriguez
2006-11-08 0:39 ` John W. Linville
0 siblings, 1 reply; 39+ messages in thread
From: Luis R. Rodriguez @ 2006-11-03 18:41 UTC (permalink / raw)
To: chunkeey@web.de; +Cc: netdev, Dan Williams
On 11/3/06, chunkeey@web.de <chunkeey@web.de> wrote:
> Am Freitag, 3. November 2006 17:06 schrieben Sie:
> > On 11/3/06, Dan Williams <dcbw@redhat.com> wrote:
> > > On Tue, 2006-10-31 at 11:05 -0500, Dan Williams wrote:
> > > > On Mon, 2006-10-30 at 15:17 -0500, Luis R. Rodriguez wrote:
> > > > > On 10/29/06, chunkeey@web.de <chunkeey@web.de> wrote:
> > > > > > This patch completes WPA/RSN with TKIP support for all fullmac
> > > > > > prism54 cards. I removed all parts which are not relevant for
> > > > > > wpa_supplicant (managed mode).
> > > > >
> > > > > This is great effort and thanks for it! My only concern with the
> > > > > patch is breaking compatiblity with 2.4 but then again I'm tired of
> > > > > having to keep this compat work up too and soon, after d80211 full
> > > > > force push it may not be possible. So I ACK it.
> > > >
> > > > I'd like to test it a bit first with my fullmac card before it gets
> > > > committed/added... But it's great to get some movement on this
> > > > card/driver!
> > >
> > > So my prism54 fullmac card appears to be broken, since it refuses to
> > > associate with anything at all, even unencrypted access points. It
> > > doesn't throw any errors at all, and it appears to be operating
> > > correctly other than not associating.
> >
> > chunkeey, I figured your patch was well tested as you had it sitting
> > there for a while I gotta find a fullmac working card (most of them
> > broke while debugging) to debug.
> >
> well, it was already tested by:
> Maxi, Dan S., Gabriel, C and "me".
> "The best configuration is: WPA2 with TKIP!"
>
> > > Is there any way to get more information out of the firmware about what
> > > it's doing?
> >
> > The driver supports prism54_get_oid and prism54_set_u32. The list of
> > OIDs available are on isl_oid.h on oid_num_t enum. Just an FYI you if
> > you need to access the *EX OIDs you just need to be in extended mode.
> > Also for WPA you need to be in extended mode. To say the least last
> > the driver was pretty unstable in extended mode last I used worked on
> > it. Dan do you get any funky mgt timeouts on your ring buffer?
> > Anything useful there?
> >
> > Luis
> yes, especially mgt_commit_list caused alot headaches, until I removed
> DOT11_OID_PSM from the cache list.
> Now, I can "hammer" it with ping -f for hours.
nice, perhaps that's been the culprit all along... going to dig to see
if I find a fullmac prism card. Will like to get this merged in.
Luis
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
2006-11-03 18:41 ` Luis R. Rodriguez
@ 2006-11-08 0:39 ` John W. Linville
2006-11-09 17:38 ` chunkeey
0 siblings, 1 reply; 39+ messages in thread
From: John W. Linville @ 2006-11-08 0:39 UTC (permalink / raw)
To: Luis R. Rodriguez; +Cc: chunkeey@web.de, netdev, Dan Williams
On Fri, Nov 03, 2006 at 01:41:46PM -0500, Luis R. Rodriguez wrote:
> On 11/3/06, chunkeey@web.de <chunkeey@web.de> wrote:
> >yes, especially mgt_commit_list caused alot headaches, until I removed
> >DOT11_OID_PSM from the cache list.
> >Now, I can "hammer" it with ping -f for hours.
>
> nice, perhaps that's been the culprit all along... going to dig to see
> if I find a fullmac prism card. Will like to get this merged in.
Any resolution on this?
--
John W. Linville
linville@tuxdriver.com
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
2006-11-08 0:39 ` John W. Linville
@ 2006-11-09 17:38 ` chunkeey
2006-11-09 23:16 ` Luis R. Rodriguez
0 siblings, 1 reply; 39+ messages in thread
From: chunkeey @ 2006-11-09 17:38 UTC (permalink / raw)
To: John W. Linville; +Cc: netdev
Am Mittwoch, 8. November 2006 01:39 schrieben Sie:
> On Fri, Nov 03, 2006 at 01:41:46PM -0500, Luis R. Rodriguez wrote:
> > On 11/3/06, chunkeey@web.de <chunkeey@web.de> wrote:
> > >yes, especially mgt_commit_list caused alot headaches, until I removed
> > >DOT11_OID_PSM from the cache list.
> > >Now, I can "hammer" it with ping -f for hours.
> >
> > nice, perhaps that's been the culprit all along... going to dig to see
> > if I find a fullmac prism card. Will like to get this merged in.
>
> Any resolution on this?
no replies.
Seems like it works for just fine for everybody. ;)
Christian
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
2006-11-09 17:38 ` chunkeey
@ 2006-11-09 23:16 ` Luis R. Rodriguez
2006-11-09 23:16 ` Luis R. Rodriguez
0 siblings, 1 reply; 39+ messages in thread
From: Luis R. Rodriguez @ 2006-11-09 23:16 UTC (permalink / raw)
To: chunkeey@web.de; +Cc: John W. Linville, netdev
On 11/9/06, chunkeey@web.de <chunkeey@web.de> wrote:
> Am Mittwoch, 8. November 2006 01:39 schrieben Sie:
> > On Fri, Nov 03, 2006 at 01:41:46PM -0500, Luis R. Rodriguez wrote:
> > > On 11/3/06, chunkeey@web.de <chunkeey@web.de> wrote:
> > > >yes, especially mgt_commit_list caused alot headaches, until I removed
> > > >DOT11_OID_PSM from the cache list.
> > > >Now, I can "hammer" it with ping -f for hours.
> > >
> > > nice, perhaps that's been the culprit all along... going to dig to see
> > > if I find a fullmac prism card. Will like to get this merged in.
> >
> > Any resolution on this?
>
> no replies.
> Seems like it works for just fine for everybody. ;)
I found a card, I just need time to test it. Dan didn't you say you
ran into issues with the patch on your card?
Luis
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
2006-11-09 23:16 ` Luis R. Rodriguez
@ 2006-11-09 23:16 ` Luis R. Rodriguez
2006-11-10 14:42 ` Dan Williams
0 siblings, 1 reply; 39+ messages in thread
From: Luis R. Rodriguez @ 2006-11-09 23:16 UTC (permalink / raw)
To: chunkeey@web.de; +Cc: John W. Linville, netdev, Dan Williams
On 11/9/06, Luis R. Rodriguez <mcgrof@gmail.com> wrote:
> On 11/9/06, chunkeey@web.de <chunkeey@web.de> wrote:
> > Am Mittwoch, 8. November 2006 01:39 schrieben Sie:
> > > On Fri, Nov 03, 2006 at 01:41:46PM -0500, Luis R. Rodriguez wrote:
> > > > On 11/3/06, chunkeey@web.de <chunkeey@web.de> wrote:
> > > > >yes, especially mgt_commit_list caused alot headaches, until I removed
> > > > >DOT11_OID_PSM from the cache list.
> > > > >Now, I can "hammer" it with ping -f for hours.
> > > >
> > > > nice, perhaps that's been the culprit all along... going to dig to see
> > > > if I find a fullmac prism card. Will like to get this merged in.
> > >
> > > Any resolution on this?
> >
> > no replies.
> > Seems like it works for just fine for everybody. ;)
>
> I found a card, I just need time to test it. Dan didn't you say you
> ran into issues with the patch on your card?
>
> Luis
CC'ing Dan to make sure he gets it ;)
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
2006-11-09 23:16 ` Luis R. Rodriguez
@ 2006-11-10 14:42 ` Dan Williams
2006-11-17 5:42 ` Dmitry Torokhov
0 siblings, 1 reply; 39+ messages in thread
From: Dan Williams @ 2006-11-10 14:42 UTC (permalink / raw)
To: Luis R. Rodriguez; +Cc: chunkeey@web.de, John W. Linville, netdev
On Thu, 2006-11-09 at 18:16 -0500, Luis R. Rodriguez wrote:
> On 11/9/06, Luis R. Rodriguez <mcgrof@gmail.com> wrote:
> > On 11/9/06, chunkeey@web.de <chunkeey@web.de> wrote:
> > > Am Mittwoch, 8. November 2006 01:39 schrieben Sie:
> > > > On Fri, Nov 03, 2006 at 01:41:46PM -0500, Luis R. Rodriguez wrote:
> > > > > On 11/3/06, chunkeey@web.de <chunkeey@web.de> wrote:
> > > > > >yes, especially mgt_commit_list caused alot headaches, until I removed
> > > > > >DOT11_OID_PSM from the cache list.
> > > > > >Now, I can "hammer" it with ping -f for hours.
> > > > >
> > > > > nice, perhaps that's been the culprit all along... going to dig to see
> > > > > if I find a fullmac prism card. Will like to get this merged in.
> > > >
> > > > Any resolution on this?
> > >
> > > no replies.
> > > Seems like it works for just fine for everybody. ;)
> >
> > I found a card, I just need time to test it. Dan didn't you say you
> > ran into issues with the patch on your card?
No, more that my card doesn't successfully associate at all even
_without_ the patch on unencrypted or WEP APs; I just can't test it,
since my card seems to be broken...
Dan
> > Luis
>
> CC'ing Dan to make sure he gets it ;)
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
2006-11-10 14:42 ` Dan Williams
@ 2006-11-17 5:42 ` Dmitry Torokhov
2006-11-17 19:43 ` chunkeey
0 siblings, 1 reply; 39+ messages in thread
From: Dmitry Torokhov @ 2006-11-17 5:42 UTC (permalink / raw)
To: Dan Williams; +Cc: Luis R. Rodriguez, chunkeey@web.de, John W. Linville, netdev
On Friday 10 November 2006 09:42, Dan Williams wrote:
> On Thu, 2006-11-09 at 18:16 -0500, Luis R. Rodriguez wrote:
> > On 11/9/06, Luis R. Rodriguez <mcgrof@gmail.com> wrote:
> > > On 11/9/06, chunkeey@web.de <chunkeey@web.de> wrote:
> > > > Am Mittwoch, 8. November 2006 01:39 schrieben Sie:
> > > > > On Fri, Nov 03, 2006 at 01:41:46PM -0500, Luis R. Rodriguez wrote:
> > > > > > On 11/3/06, chunkeey@web.de <chunkeey@web.de> wrote:
> > > > > > >yes, especially mgt_commit_list caused alot headaches, until I removed
> > > > > > >DOT11_OID_PSM from the cache list.
> > > > > > >Now, I can "hammer" it with ping -f for hours.
> > > > > >
> > > > > > nice, perhaps that's been the culprit all along... going to dig to see
> > > > > > if I find a fullmac prism card. Will like to get this merged in.
> > > > >
> > > > > Any resolution on this?
> > > >
> > > > no replies.
> > > > Seems like it works for just fine for everybody. ;)
> > >
> > > I found a card, I just need time to test it. Dan didn't you say you
> > > ran into issues with the patch on your card?
>
> No, more that my card doesn't successfully associate at all even
> _without_ the patch on unencrypted or WEP APs; I just can't test it,
> since my card seems to be broken...
>
FWIW I applied the patch to tonight pull form Linus's tree and my card
stopped associating with my AP (WEP128, Shared key). It only associated
with my neighbour router which is running without encryption.
--
Dmitry
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
2006-11-17 5:42 ` Dmitry Torokhov
@ 2006-11-17 19:43 ` chunkeey
2006-11-17 20:16 ` Dmitry Torokhov
0 siblings, 1 reply; 39+ messages in thread
From: chunkeey @ 2006-11-17 19:43 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: netdev
Am Freitag, 17. November 2006 06:42 schrieben Sie:
> >
> > No, more that my card doesn't successfully associate at all even
> > _without_ the patch on unencrypted or WEP APs; I just can't test it,
> > since my card seems to be broken...
>
> FWIW I applied the patch to tonight pull form Linus's tree and my card
> stopped associating with my AP (WEP128, Shared key). It only associated
> with my neighbour router which is running without encryption.
can you please describe your setup? I tested WEP ("restricted") with a Netgear
WGT624 and a normal linux AP and haven't seen any problems so far.
for debugging:
dmesg & iwevent output would be nice...
but I'll accept a short "sniffer" extract too. ;)
(it would be really good, if you can provide a package dump form a working
setup with the old driver too!)
Christian
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
2006-11-17 19:43 ` chunkeey
@ 2006-11-17 20:16 ` Dmitry Torokhov
2006-11-17 20:53 ` chunkeey
0 siblings, 1 reply; 39+ messages in thread
From: Dmitry Torokhov @ 2006-11-17 20:16 UTC (permalink / raw)
To: chunkeey@web.de; +Cc: netdev
On 11/17/06, chunkeey@web.de <chunkeey@web.de> wrote:
> Am Freitag, 17. November 2006 06:42 schrieben Sie:
> > >
> > > No, more that my card doesn't successfully associate at all even
> > > _without_ the patch on unencrypted or WEP APs; I just can't test it,
> > > since my card seems to be broken...
> >
> > FWIW I applied the patch to tonight pull form Linus's tree and my card
> > stopped associating with my AP (WEP128, Shared key). It only associated
> > with my neighbour router which is running without encryption.
> can you please describe your setup? I tested WEP ("restricted") with a Netgear
> WGT624 and a normal linux AP and haven't seen any problems so far.
>
The card is WG511 talking to netgear WGR614 router. I am using WEP128
with shared keys. Router is set to be "g" only. The OS is Fedora Core
3 (I swear I will upgrade :) ), just recompiled wireless tools from
sources in FC6.
> for debugging:
> dmesg & iwevent output would be nice...
Will do when I get home.
> but I'll accept a short "sniffer" extract too. ;)
>
> (it would be really good, if you can provide a package dump form a working
> setup with the old driver too!)
>
You'd have to tell me exactly what you want me to do.
The reason for me trying the patch is that the card locks up
frequently (the amber transmission light turns on stays this way).
--
Dmitry
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
2006-11-17 20:16 ` Dmitry Torokhov
@ 2006-11-17 20:53 ` chunkeey
2006-11-17 21:02 ` Dmitry Torokhov
2006-11-18 4:27 ` Dmitry Torokhov
0 siblings, 2 replies; 39+ messages in thread
From: chunkeey @ 2006-11-17 20:53 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: netdev
>
> The card is WG511 talking to netgear WGR614 router. I am using WEP128
> with shared keys. Router is set to be "g" only. The OS is Fedora Core
> 3 (I swear I will upgrade :) ), just recompiled wireless tools from
> sources in FC6.
>
> > for debugging:
> > dmesg & iwevent output would be nice...
>
> Will do when I get home.
>
> > but I'll accept a short "sniffer" extract too. ;)
> >
> > (it would be really good, if you can provide a package dump form a
> > working setup with the old driver too!)
>
> You'd have to tell me exactly what you want me to do.
just the Management Frames (MLME):
Beacon, Authentication and Association Responses/Requests Frames
you can capture these frames with an extra sniffer card (in monitor mode)
just run tcpdump, wireshark(ethereal), kismet, ...
>
> The reason for me trying the patch is that the card locks up
> frequently (the amber transmission light turns on stays this way).
Do you get any fancy "mgt timeout ..." or something in dmesg, when
the cards locks up? (include one, if you can, maybe syslog "saved" one)
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
2006-11-17 20:53 ` chunkeey
@ 2006-11-17 21:02 ` Dmitry Torokhov
2006-11-17 21:09 ` Dmitry Torokhov
2006-11-18 4:27 ` Dmitry Torokhov
1 sibling, 1 reply; 39+ messages in thread
From: Dmitry Torokhov @ 2006-11-17 21:02 UTC (permalink / raw)
To: chunkeey@web.de; +Cc: netdev
On 11/17/06, chunkeey@web.de <chunkeey@web.de> wrote:
> >
> > The reason for me trying the patch is that the card locks up
> > frequently (the amber transmission light turns on stays this way).
>
> Do you get any fancy "mgt timeout ..." or something in dmesg, when
> the cards locks up? (include one, if you can, maybe syslog "saved" one)
>
I think I saw these before (with earlier kernels, can't tell you
exactly when it stopped as I don't pay much attention to versions - I
work off tip of Linus's tree and pull often) but now it looks like it
simply locks up. Maybe I don't wait long enough - I just simply eject
and inster the card back when I see it locked up.
--
Dmitry
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
2006-11-17 21:02 ` Dmitry Torokhov
@ 2006-11-17 21:09 ` Dmitry Torokhov
2006-11-17 21:35 ` chunkeey
0 siblings, 1 reply; 39+ messages in thread
From: Dmitry Torokhov @ 2006-11-17 21:09 UTC (permalink / raw)
To: chunkeey@web.de; +Cc: netdev
On 11/17/06, Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote:
> On 11/17/06, chunkeey@web.de <chunkeey@web.de> wrote:
> > >
> > > The reason for me trying the patch is that the card locks up
> > > frequently (the amber transmission light turns on stays this way).
> >
> > Do you get any fancy "mgt timeout ..." or something in dmesg, when
> > the cards locks up? (include one, if you can, maybe syslog "saved" one)
> >
>
> I think I saw these before (with earlier kernels, can't tell you
> exactly when it stopped as I don't pay much attention to versions - I
> work off tip of Linus's tree and pull often) but now it looks like it
> simply locks up. Maybe I don't wait long enough - I just simply eject
> and inster the card back when I see it locked up.
>
Btw, it usually locks up under heavyish load. I.e. if I just ssh into
my devel box and code in vi it will stay jsut fine for hours. But
FTPing stuff over quite often locks it up.
--
Dmitry
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
2006-11-17 21:09 ` Dmitry Torokhov
@ 2006-11-17 21:35 ` chunkeey
0 siblings, 0 replies; 39+ messages in thread
From: chunkeey @ 2006-11-17 21:35 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: netdev
>
> Btw, it usually locks up under heavyish load. I.e. if I just ssh into
> my devel box and code in vi it will stay jsut fine for hours. But
> FTPing stuff over quite often locks it up.
k, I've seen this phenomenon too, but on my a PCI card.
Alright, when you come home, you should check the syslogs for these
kind of "timeout" messages.
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
2006-11-17 20:53 ` chunkeey
2006-11-17 21:02 ` Dmitry Torokhov
@ 2006-11-18 4:27 ` Dmitry Torokhov
2006-11-18 10:18 ` chunkeey
1 sibling, 1 reply; 39+ messages in thread
From: Dmitry Torokhov @ 2006-11-18 4:27 UTC (permalink / raw)
To: chunkeey; +Cc: netdev
On Friday 17 November 2006 15:53, chunkeey@web.de wrote:
> >
> > The card is WG511 talking to netgear WGR614 router. I am using WEP128
> > with shared keys. Router is set to be "g" only. The OS is Fedora Core
> > 3 (I swear I will upgrade :) ), just recompiled wireless tools from
> > sources in FC6.
> >
> > > for debugging:
> > > dmesg & iwevent output would be nice...
> >
> > Will do when I get home.
> >
> > > but I'll accept a short "sniffer" extract too. ;)
> > >
> > > (it would be really good, if you can provide a package dump form a
> > > working setup with the old driver too!)
> >
> > You'd have to tell me exactly what you want me to do.
> just the Management Frames (MLME):
> Beacon, Authentication and Association Responses/Requests Frames
> you can capture these frames with an extra sniffer card (in monitor mode)
> just run tcpdump, wireshark(ethereal), kismet, ...
>
OK, i'll try installing kismet on another laptop. For now that's what I have
from iwevent:
[root@core ~]# cat iwevents.bad
21:30:52.185823 eth1 Set Mode:Managed
21:30:52.226100 eth1 Set ESSID:"ALCT76_68b"
21:30:54.505039 eth1 Custom driver event:Authenticate request to 00:0f:b5:5b:fe:3a [00 0D 0002]
21:30:56.300128 eth1 Custom driver event:Authenticate request to 00:0f:b5:5b:fe:3a [00 0D 0002]
21:30:58.095251 eth1 Custom driver event:Authenticate request to 00:0f:b5:5b:fe:3a [00 0D 0002]
21:31:11.413225 eth1 Custom driver event:Authenticate request to 00:0f:b5:5b:fe:3a [00 0D 0002]
21:31:13.207322 eth1 Custom driver event:Authenticate request to 00:0f:b5:5b:fe:3a [00 0D 0002]
21:31:15.003497 eth1 Custom driver event:Authenticate request to 00:0f:b5:5b:fe:3a [00 0D 0002]
21:31:16.798687 eth1 Custom driver event:Authenticate request to 00:0f:b5:5b:fe:3a [00 0D 0002]
21:31:18.593844 eth1 Custom driver event:Authenticate request to 00:0f:b5:5b:fe:3a [00 0D 0002]
21:31:31.911710 eth1 Custom driver event:Authenticate request to 00:0f:b5:5b:fe:3a [00 0D 0002]
21:31:33.705200 eth1 Custom driver event:Authenticate request to 00:0f:b5:5b:fe:3a [00 0D 0002]
21:31:35.501650 eth1 Custom driver event:Authenticate request to 00:0f:b5:5b:fe:3a [00 0D 0002]
21:31:37.296756 eth1 Custom driver event:Authenticate request to 00:0f:b5:5b:fe:3a [00 0D 0002]
21:31:39.091866 eth1 Custom driver event:Authenticate request to 00:0f:b5:5b:fe:3a [00 0D 0002]
21:31:52.409596 eth1 Custom driver event:Authenticate request to 00:0f:b5:5b:fe:3a [00 0D 0002]
21:31:54.203281 eth1 Custom driver event:Authenticate request to 00:0f:b5:5b:fe:3a [00 0D 0002]
[root@core ~]# cat iwevents.good
21:50:50.575630 eth1 Set Mode:Managed
21:50:50.604998 eth1 Set Encryption key:****-****-****-****-****-****-** Security mode:restricted
21:50:50.616502 eth1 Set ESSID:"ALCT76_68b"
21:50:52.880361 eth1 Custom driver event:Authenticate request to 00:0F:B5:5B:FE:3A : ACCEPTED (00)
21:50:52.882638 eth1 Custom driver event:Associate request to 00:0F:B5:5B:FE:3A : ACCEPTED (00)
21:50:52.883625 eth1 New Access Point/Cell address:00:0F:B5:5B:FE:3A
>
> >
> > The reason for me trying the patch is that the card locks up
> > frequently (the amber transmission light turns on stays this way).
>
> Do you get any fancy "mgt timeout ..." or something in dmesg, when
> the cards locks up? (include one, if you can, maybe syslog "saved" one)
>
No, just netdev watchdog bitches:
Nov 16 23:15:30 core kernel: [164606.712000] NETDEV WATCHDOG: eth1: transmit timed out
Nov 16 23:15:30 core kernel: [164606.712000] eth1: tx_timeout, scheduling a reset
Nov 16 23:15:30 core kernel: [164606.712000] eth1: resetting device...
Nov 16 23:15:30 core kernel: [164606.712000] eth1: uploading firmware...
Nov 16 23:15:31 core kernel: [164606.996000] eth1: firmware version: 1.0.4.3
Nov 16 23:15:31 core kernel: [164606.996000] eth1: firmware upload complete
Nov 16 23:15:31 core kernel: [164607.232000] eth1: interface reset complete
--
Dmitry
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
2006-11-18 4:27 ` Dmitry Torokhov
@ 2006-11-18 10:18 ` chunkeey
2006-11-22 7:01 ` Dmitry Torokhov
0 siblings, 1 reply; 39+ messages in thread
From: chunkeey @ 2006-11-18 10:18 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: netdev
Am Samstag, 18. November 2006 05:27 schrieben Sie:
>
> OK, i'll try installing kismet on another laptop. For now that's what I
> have from iwevent:
>
> [root@core ~]# cat iwevents.bad
> 21:30:52.185823 eth1 Set Mode:Managed
where's Set Encryption key:****-****-****-****-****-****-** Security
mode:restricted ? was the key set?
> 21:30:52.226100 eth1 Set ESSID:"ALCT76_68b"
> 21:30:54.505039 eth1 Authenticate request to XY [00 0D 0002]
> 21:30:56.300128 eth1 Authenticate request to XY [00 0D 0002]
ok, the error code is 0D (=unsupported Authentication Algorithm).
>
> [root@core ~]# cat iwevents.good
> 21:50:50.575630 eth1 Set Mode:Managed
> 21:50:50.604998 eth1 Set Encryption
> key:****-****-****-****-****-****-** Security mode:restricted
> 21:50:50.616502 eth1 Set ESSID:"ALCT76_68b"
> 21:50:52.880361 eth1 Authenticate request to XY : [00 00 0002]
> 21:50:52.882638 eth1 Associate request to XY : [00 00 0002]
> 21:50:52.883625 eth1 New Access Point/Cell address:XY
are your wireless-tools( iwconfig, iwevent, iwlist...) up to date? they've to
be atleast Version 21!
but there's still something you can try:
go to drivers/net/wireless/prism54/isl_ioctl.c
and change in "prism54_set_auth_alg" function (somewhere at line 1040)
next to "if (flag & IW_ENCODE_RESTRICTED) {"
authen = DOT11_AUTH_SK;
to
authen = DOT11_AUTH_BOTH;
recompile; test; report ;)
>
> No, just netdev watchdog bitches:
>
> Nov 16 23:15:30 core kernel: [164606.712000] NETDEV WATCHDOG: eth1:
> transmit timed out Nov 16 23:15:30 core kernel: [164606.712000] eth1:
> tx_timeout, scheduling a reset Nov 16 23:15:30 core kernel: [164606.712000]
> eth1: resetting device... Nov 16 23:15:30 core kernel: [164606.712000]
> eth1: uploading firmware... Nov 16 23:15:31 core kernel: [164606.996000]
> eth1: firmware version: 1.0.4.3 Nov 16 23:15:31 core kernel:
> [164606.996000] eth1: firmware upload complete Nov 16 23:15:31 core kernel:
> [164607.232000] eth1: interface reset complete
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
2006-11-18 10:18 ` chunkeey
@ 2006-11-22 7:01 ` Dmitry Torokhov
2006-11-24 15:55 ` chunkeey
[not found] ` <200611250039.03597.dtor@insightbb.com>
0 siblings, 2 replies; 39+ messages in thread
From: Dmitry Torokhov @ 2006-11-22 7:01 UTC (permalink / raw)
To: chunkeey; +Cc: netdev
On Saturday 18 November 2006 05:18, chunkeey@web.de wrote:
> Am Samstag, 18. November 2006 05:27 schrieben Sie:
> >
> > OK, i'll try installing kismet on another laptop. For now that's what I
> > have from iwevent:
> >
> > [root@core ~]# cat iwevents.bad
> > 21:30:52.185823 eth1 Set Mode:Managed
> where's Set Encryption key:****-****-****-****-****-****-** Security
> mode:restricted ? was the key set?
>
>
> > 21:30:52.226100 eth1 Set ESSID:"ALCT76_68b"
> > 21:30:54.505039 eth1 Authenticate request to XY [00 0D 0002]
> > 21:30:56.300128 eth1 Authenticate request to XY [00 0D 0002]
> ok, the error code is 0D (=unsupported Authentication Algorithm).
>
> >
> > [root@core ~]# cat iwevents.good
> > 21:50:50.575630 eth1 Set Mode:Managed
> > 21:50:50.604998 eth1 Set Encryption
> > key:****-****-****-****-****-****-** Security mode:restricted
> > 21:50:50.616502 eth1 Set ESSID:"ALCT76_68b"
> > 21:50:52.880361 eth1 Authenticate request to XY : [00 00 0002]
> > 21:50:52.882638 eth1 Associate request to XY : [00 00 0002]
> > 21:50:52.883625 eth1 New Access Point/Cell address:XY
> are your wireless-tools( iwconfig, iwevent, iwlist...) up to date? they've to
> be atleast Version 21!
>
Hmm, something funky is going on with my hotplug scripts - if I rerun
ifup eth1 after inserting the card it associates just fine. Sorry for
the false alarm, the drivers seems to be working fine.
Still not sure why old driver does not need second "ifup"...
--
Dmitry
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
2006-11-22 7:01 ` Dmitry Torokhov
@ 2006-11-24 15:55 ` chunkeey
[not found] ` <200611250039.03597.dtor@insightbb.com>
1 sibling, 0 replies; 39+ messages in thread
From: chunkeey @ 2006-11-24 15:55 UTC (permalink / raw)
To: netdev
On Wednesday, 22. November 2006 08:01, you wrote:
>
> Hmm, something funky is going on with my hotplug scripts - if I rerun
> ifup eth1 after inserting the card it associates just fine. Sorry for
> the false alarm, the drivers seems to be working fine.
>
> Still not sure why old driver does not need second "ifup"...
old drivers? which one? the svn? 2.6.18?
Since, the card doesn't associate with WPA protected wlans automaticlly,
but what about WEP or unprotected wlans?
It would be nice if someone can capture the MLME frames and look
if the card does the right thing.
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
[not found] ` <200611250039.03597.dtor@insightbb.com>
@ 2006-11-25 16:50 ` chunkeey
2006-11-26 5:27 ` Dmitry Torokhov
0 siblings, 1 reply; 39+ messages in thread
From: chunkeey @ 2006-11-25 16:50 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: netdev, linville, Dan Williams, Christian Lamparter
[-- Attachment #1: Type: text/plain, Size: 1057 bytes --]
On Saturday, 25. November 2006 06:39, you wrote:
> Ok, it looks like the patch changed the order of netdevice registration vs.
> requesting firmware. My scripts are trying to set ESSID and keys before
> firmware even gets loaded into the card. You may want to make sure that
> newer distributions immune to such change before pushing the patch to
> mainline.
Ok, I think I know what was "wrong", this new patch should fix the problem.
Can you try it?
btw, just for the records: (ping -f ~3 hours)
eth2 Link encap:Ethernet HWaddr 00:01:36:0D:XX:XX
inet addr:192.168.1.6 Bcast:192.168.1.255 Mask:255.255.255.0
inet6 addr: fe80::201:36ff:fe0d:d239/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:9267081 errors:0 dropped:0 overruns:0 frame:0
TX packets:9267183 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:958462385 (914.0 MiB) TX bytes:958454367 (914.0 MiB)
Interrupt:18 Base address:0x8000
Christian.
[-- Attachment #2: prism54-wpa-wl2.6-git.diff --]
[-- Type: text/x-diff, Size: 78731 bytes --]
diff --git a/drivers/net/wireless/prism54/isl_38xx.c b/drivers/net/wireless/prism54/isl_38xx.c
index 02fc67b..044a23f 100644
--- a/drivers/net/wireless/prism54/isl_38xx.c
+++ b/drivers/net/wireless/prism54/isl_38xx.c
@@ -24,7 +24,6 @@
#include <asm/uaccess.h>
#include <asm/io.h>
-#include "prismcompat.h"
#include "isl_38xx.h"
#include "islpci_dev.h"
#include "islpci_mgt.h"
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 4a20e45..63a8920 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -3,6 +3,7 @@
* (C) 2003,2004 Aurelien Alleaume <slts@free.fr>
* (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
* (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
+ * (C) 2006 Christian Lamparter <chunkeey@web.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,18 +27,13 @@
#include <asm/uaccess.h>
-#include "prismcompat.h"
#include "isl_ioctl.h"
#include "islpci_mgt.h"
#include "isl_oid.h" /* additional types and defs for isl38xx fw */
#include "oid_mgt.h"
#include <net/iw_handler.h> /* New driver API */
-
-#define KEY_SIZE_WEP104 13 /* 104/128-bit WEP keys */
-#define KEY_SIZE_WEP40 5 /* 40/64-bit WEP keys */
-/* KEY_SIZE_TKIP should match isl_oid.h, struct obj_key.key[] size */
-#define KEY_SIZE_TKIP 32 /* TKIP keys */
+#include <net/ieee80211.h>
static void prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid,
u8 *wpa_ie, size_t wpa_ie_len);
@@ -45,11 +41,6 @@ static size_t prism54_wpa_bss_ie_get(isl
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
@@ -167,14 +158,16 @@ prism54_update_stats(islpci_private *pri
if (down_interruptible(&priv->stats_sem))
return;
-/* Noise floor.
- * I'm not sure if the unit is dBm.
- * Note : If we are not connected, this value seems to be irrelevant. */
+ /* Noise floor.
+ * I'm not sure if the unit is dBm.
+
+ * Note :
+ * If we are not connected, this value seems to be irrelevant. */
mgt_get_request(priv, DOT11_OID_NOISEFLOOR, 0, NULL, &r);
priv->local_iwstatistics.qual.noise = r.u;
-/* Get the rssi of the link. To do this we need to retrieve a bss. */
+ /* Get the rssi of the link. To do this we need to retrieve a bss. */
/* First get the MAC address of the AP we are associated with. */
mgt_get_request(priv, DOT11_OID_BSSID, 0, NULL, &r);
@@ -199,11 +192,11 @@ prism54_update_stats(islpci_private *pri
/* report that the stats are new */
priv->local_iwstatistics.qual.updated = 0x7;
-/* Rx : unable to decrypt the MPDU */
+ /* Rx : unable to decrypt the MPDU */
mgt_get_request(priv, DOT11_OID_PRIVRXFAILED, 0, NULL, &r);
priv->local_iwstatistics.discard.code = r.u;
-/* Tx : Max MAC retries num reached */
+ /* Tx : Max MAC retries num reached */
mgt_get_request(priv, DOT11_OID_MPDUTXFAILED, 0, NULL, &r);
priv->local_iwstatistics.discard.retries = r.u;
@@ -227,7 +220,7 @@ prism54_get_wireless_stats(struct net_de
} else
priv->iwstatistics.qual.updated = 0;
- /* Update our wireless stats, but do not schedule to often
+ /* Update our wireless stats, but do not schedule too often
* (max 1 HZ) */
if ((priv->stats_timestamp == 0) ||
time_after(jiffies, priv->stats_timestamp + 1 * HZ)) {
@@ -414,6 +407,8 @@ prism54_get_sens(struct net_device *ndev
return rvalue;
}
+#define WEP40_KEY_LEN 5 /* 40/64-bit WEP keys */
+
static int
prism54_get_range(struct net_device *ndev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
@@ -435,11 +430,11 @@ prism54_get_range(struct net_device *nde
/* Now the encoding capabilities */
range->num_encoding_sizes = 3;
/* 64(40) bits WEP */
- range->encoding_size[0] = 5;
+ range->encoding_size[0] = WEP40_KEY_LEN;
/* 128(104) bits WEP */
- range->encoding_size[1] = 13;
+ range->encoding_size[1] = WEP_KEY_LEN;
/* 256 bits for WPA-PSK */
- range->encoding_size[2] = 32;
+ range->encoding_size[2] = SCM_KEY_LEN;
/* 4 keys are allowed */
range->max_encoding_tokens = 4;
@@ -565,6 +560,11 @@ prism54_set_scan(struct net_device *dev,
return 0;
}
+/* In 500 kbps */
+static const unsigned char scan_rate_list[] = { 2, 4, 11, 22,
+ 12, 18, 24, 36,
+ 48, 72, 96, 108 };
+
/* a little helper that will translate our data into a card independent
* format that the Wireless Tools will understand. This was inspired by
* the "Aironet driver for 4500 and 4800 series cards" (GPL)
@@ -596,17 +596,12 @@ prism54_translate_bss(struct net_device
current_ev = iwe_stream_add_point(current_ev, end_buf,
&iwe, bss->ssid.octets);
- /* Capabilities */
-#define CAP_ESS 0x01
-#define CAP_IBSS 0x02
-#define CAP_CRYPT 0x10
-
/* Mode */
cap = bss->capinfo;
iwe.u.mode = 0;
- if (cap & CAP_ESS)
+ if (cap & WLAN_CAPABILITY_ESS)
iwe.u.mode = IW_MODE_MASTER;
- else if (cap & CAP_IBSS)
+ else if (cap & WLAN_CAPABILITY_IBSS)
iwe.u.mode = IW_MODE_ADHOC;
iwe.cmd = SIOCGIWMODE;
if (iwe.u.mode)
@@ -615,7 +610,7 @@ prism54_translate_bss(struct net_device
IW_EV_UINT_LEN);
/* Encryption capability */
- if (cap & CAP_CRYPT)
+ if (cap & WLAN_CAPABILITY_PRIVACY)
iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
@@ -875,15 +870,6 @@ prism54_set_rate(struct net_device *ndev
data[1] = 0;
}
-/*
- i = 0;
- printk("prism54 rate: ");
- while(data[i]) {
- printk("%u ", data[i]);
- i++;
- }
- printk("0\n");
-*/
profile = -1;
ret = mgt_set_request(priv, DOT11_OID_PROFILES, 0, &profile);
ret |= mgt_set_request(priv, DOT11_OID_EXTENDEDRATES, 0, data);
@@ -1052,12 +1038,49 @@ prism54_get_retry(struct net_device *nde
}
static int
+prism54_set_auth_alg(islpci_private *priv, u32 flag)
+{
+ int authen = DOT11_AUTH_NONE, invoke = 0, exunencrypt = 0;
+ int ret;
+
+ if (flag & IW_ENCODE_RESTRICTED) {
+ authen = DOT11_AUTH_SK;
+ invoke = 1;
+ exunencrypt = 1;
+ }
+
+ if (flag & IW_ENCODE_OPEN) {
+ authen = DOT11_AUTH_OS;
+ invoke = 1;
+ /*
+ This is very wrong here, but we've to ensure bug-to-bug compatibility.
+
+ If we set exunencrypt, the Firmware adds the "Privacy" flag to the
+ Capability Information, which is misreaded by many STA/AP as
+ "the device supports WEP, WPA and WPA2"
+ */
+ exunencrypt = 1;
+ }
+
+ ret =
+ mgt_set_request(priv, DOT11_OID_AUTHENABLE,
+ 0, &authen);
+ ret |=
+ mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED,
+ 0, &invoke);
+ ret |=
+ mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED,
+ 0,&exunencrypt);
+
+ return ret;
+}
+
+static int
prism54_set_encode(struct net_device *ndev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
- int rvalue = 0, force = 0;
- int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0;
+ int rvalue = 0, flags = dwrq->flags;
union oid_res_t r;
/* with the new API, it's impossible to get a NULL pointer.
@@ -1071,27 +1094,27 @@ prism54_set_encode(struct net_device *nd
struct obj_key key = { DOT11_PRIV_WEP, 0, "" };
/* get the current key index */
- rvalue = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
+ rvalue |= mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
current_index = r.u;
/* Verify that the key is not marked as invalid */
if (!(dwrq->flags & IW_ENCODE_NOKEY)) {
- if (dwrq->length > KEY_SIZE_TKIP) {
+ if (dwrq->length > MAX_KEY_LEN) {
/* User-provided key data too big */
return -EINVAL;
}
- if (dwrq->length > KEY_SIZE_WEP104) {
+ if (dwrq->length > WEP_KEY_LEN) {
/* WPA-PSK TKIP */
key.type = DOT11_PRIV_TKIP;
- key.length = KEY_SIZE_TKIP;
- } else if (dwrq->length > KEY_SIZE_WEP40) {
+ key.length = MAX_KEY_LEN;
+ } else if (dwrq->length > WEP40_KEY_LEN) {
/* WEP 104/128 */
- key.length = KEY_SIZE_WEP104;
+ key.length = WEP_KEY_LEN;
} else {
/* WEP 40/64 */
- key.length = KEY_SIZE_WEP40;
+ key.length = WEP40_KEY_LEN;
}
memset(key.key, 0, sizeof (key.key));
- memcpy(key.key, extra, dwrq->length);
+ memcpy(key.key, extra, key.length);
if ((index < 0) || (index > 3))
/* no index provided use the current one */
@@ -1108,95 +1131,111 @@ prism54_set_encode(struct net_device *nd
* This is also how "iwconfig ethX key on" works
*/
if ((index == current_index) && (key.length > 0))
- force = 1;
+ flags |= IW_ENCODE_RESTRICTED;
} else {
- int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
+ int index = (flags & IW_ENCODE_INDEX) - 1;
if ((index >= 0) && (index <= 3)) {
/* we want to set the key index */
rvalue |=
mgt_set_request(priv, DOT11_OID_DEFKEYID, 0,
&index);
} else {
- if (!dwrq->flags & IW_ENCODE_MODE) {
+ if (!(flags & IW_ENCODE_MODE)) {
/* we cannot do anything. Complain. */
return -EINVAL;
}
}
}
- /* now read the flags */
- if (dwrq->flags & IW_ENCODE_DISABLED) {
- /* Encoding disabled,
- * authen = DOT11_AUTH_OS;
- * invoke = 0;
- * exunencrypt = 0; */
- }
- if (dwrq->flags & IW_ENCODE_OPEN)
- /* Encode but accept non-encoded packets. No auth */
- invoke = 1;
- if ((dwrq->flags & IW_ENCODE_RESTRICTED) || force) {
- /* Refuse non-encoded packets. Auth */
- authen = DOT11_AUTH_BOTH;
- invoke = 1;
- exunencrypt = 1;
- }
/* do the change if requested */
- if ((dwrq->flags & IW_ENCODE_MODE) || force) {
- rvalue |=
- mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
- rvalue |=
- mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &invoke);
- rvalue |=
- mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0,
- &exunencrypt);
- }
+ if (flags & IW_ENCODE_MODE)
+ rvalue = prism54_set_auth_alg(priv, flags);
+
return rvalue;
}
static int
+prism54_get_auth_algs(islpci_private *priv)
+{
+ u32 authen = 0, invoke = 0, exunencrypt = 0;
+ union oid_res_t r;
+ int ret = 0;
+
+ ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
+ authen = r.u;
+ ret |= mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
+ invoke = r.u;
+ ret |= mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
+ exunencrypt = r.u;
+
+ if (ret)
+ return ret;
+
+ if (invoke && exunencrypt &&
+ ((authen == DOT11_AUTH_SK) || (authen == DOT11_AUTH_BOTH)))
+ ret = IW_ENCODE_RESTRICTED | IW_ENCODE_ENABLED;
+ else if ((authen == DOT11_AUTH_OS)) {
+ if (invoke)
+ ret = IW_ENCODE_OPEN | IW_ENCODE_ENABLED;
+ else {
+ ret = IW_ENCODE_DISABLED;
+ }
+ }
+ else {
+ ret = IW_ENCODE_DISABLED;
+ }
+
+ return ret;
+}
+
+static int
prism54_get_encode(struct net_device *ndev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
struct obj_key *key;
u32 devindex, index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
- u32 authen = 0, invoke = 0, exunencrypt = 0;
- int rvalue;
+ int rvalue = 0, flags;
union oid_res_t r;
+ if (islpci_get_state(priv) < PRV_STATE_INIT) {
+ dwrq->flags = IW_ENCODE_DISABLED;
+ dwrq->length = 0;
+ return 0;
+ }
+
/* first get the flags */
- rvalue = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
- authen = r.u;
- rvalue |= mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
- invoke = r.u;
- rvalue |= mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
- exunencrypt = r.u;
+ if ((flags = prism54_get_auth_algs(priv)) < 0)
+ return rvalue;
- if (invoke && (authen == DOT11_AUTH_BOTH) && exunencrypt)
- dwrq->flags = IW_ENCODE_RESTRICTED;
- else if ((authen == DOT11_AUTH_OS) && !exunencrypt) {
- if (invoke)
- dwrq->flags = IW_ENCODE_OPEN;
- else
- dwrq->flags = IW_ENCODE_DISABLED;
- } else
- /* The card should not work in this state */
- dwrq->flags = 0;
+ memset(extra, 0x0, dwrq->length);
+ dwrq->flags = flags;
- /* get the current device key index */
- 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))
- /* no index provided, use the current one */
- index = devindex;
- rvalue |= mgt_get_request(priv, DOT11_OID_DEFKEYX, index, NULL, &r);
- key = r.ptr;
- dwrq->length = key->length;
- memcpy(extra, key->key, dwrq->length);
- kfree(key);
- /* return the used key index */
- dwrq->flags |= devindex + 1;
+ if (flags != IW_ENCODE_DISABLED) {
+ /* get the current device key index */
+ 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))
+ /* no index provided, use the current one */
+ index = devindex;
+
+ rvalue |= mgt_get_request(priv, DOT11_OID_DEFKEYX, index, NULL, &r);
+ key = r.ptr;
+
+ if (dwrq->length < key->length) {
+ kfree(key);
+ return -EINVAL;
+ }
+ dwrq->length = key->length;
+ memcpy(extra, key->key, dwrq->length);
+ kfree(key);
+ /* return the used key index */
+ dwrq->flags |= devindex + 1;
+ } else
+ rvalue = 0;
+
return rvalue;
}
@@ -1212,7 +1251,7 @@ prism54_get_txpower(struct net_device *n
/* intersil firmware operates in 0.25 dBm (1/4 dBm) */
vwrq->value = (s32) r.u / 4;
vwrq->fixed = 1;
- /* radio is not turned of
+ /* radio is not turned off
* btw: how is possible to turn off only the radio
*/
vwrq->disabled = 0;
@@ -1246,58 +1285,72 @@ prism54_set_txpower(struct net_device *n
}
}
-static int prism54_set_genie(struct net_device *ndev,
- struct iw_request_info *info,
- struct iw_point *data, char *extra)
+static int
+prism54_set_attachment(islpci_private *priv, u8 frame_type,
+ int length, u8* attachment)
{
- islpci_private *priv = netdev_priv(ndev);
- int alen, ret = 0;
+ struct obj_attachment null_attach;
struct obj_attachment *attach;
+ int ret;
+
+ attach = kzalloc(sizeof(*attach) + length, GFP_KERNEL);
+ if (!attach)
+ return -ENOMEM;
+
+ memset(&null_attach, 0, sizeof(null_attach));
+
+ /* Note: endianness is covered by mgt_set_varlen */
+ null_attach.id = attach->id = -1; // use the global ID
+ attach->size = length;
+ attach->type = frame_type;
+ memcpy(attach->data, attachment, length);
+
+ /* clear the last element, before set the new one */
+ ret = mgt_set_request(priv, DOT11_OID_ATTACHMENT, 0 ,&null_attach);
+ ret |= mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach, length);
+
+ kfree(attach);
+
+ return ret;
+}
+
+static int
+prism54_set_genie(struct net_device *ndev, struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ islpci_private *priv = netdev_priv(ndev);
+ int ret = 0;
if (data->length > MAX_WPA_IE_LEN ||
(data->length && extra == NULL))
return -EINVAL;
+ if (islpci_get_state(priv) < PRV_STATE_INIT)
+ return -EINVAL;
+
memcpy(priv->wpa_ie, extra, data->length);
priv->wpa_ie_len = data->length;
- alen = sizeof(*attach) + priv->wpa_ie_len;
- attach = kzalloc(alen, GFP_KERNEL);
- if (attach == NULL)
- return -ENOMEM;
-
-#define WLAN_FC_TYPE_MGMT 0
-#define WLAN_FC_STYPE_ASSOC_REQ 0
-#define WLAN_FC_STYPE_REASSOC_REQ 2
-
- /* Note: endianness is covered by mgt_set_varlen */
- attach->type = (WLAN_FC_TYPE_MGMT << 2) |
- (WLAN_FC_STYPE_ASSOC_REQ << 4);
- attach->id = -1;
- attach->size = priv->wpa_ie_len;
- memcpy(attach->data, extra, priv->wpa_ie_len);
-
- ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach,
- priv->wpa_ie_len);
- if (ret == 0) {
- attach->type = (WLAN_FC_TYPE_MGMT << 2) |
- (WLAN_FC_STYPE_REASSOC_REQ << 4);
-
- ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach,
- priv->wpa_ie_len);
- if (ret == 0)
- printk(KERN_DEBUG "%s: WPA IE Attachment was set\n",
- ndev->name);
+ if (priv->iw_mode == IW_MODE_MASTER) {
+ ret = prism54_set_attachment(priv, IEEE80211_STYPE_PROBE_RESP,
+ data->length, extra);
+ ret |= prism54_set_attachment(priv, IEEE80211_STYPE_BEACON,
+ data->length, extra);
+ }
+ else {
+ ret = prism54_set_attachment(priv, IEEE80211_STYPE_REASSOC_REQ,
+ data->length, extra);
+ ret |= prism54_set_attachment(priv, IEEE80211_STYPE_ASSOC_REQ,
+ data->length, extra);
}
- kfree(attach);
return ret;
}
-static int prism54_get_genie(struct net_device *ndev,
- struct iw_request_info *info,
- struct iw_point *data, char *extra)
+static int
+prism54_get_genie(struct net_device *ndev, struct iw_request_info *info,
+ struct iw_point *data, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
int len = priv->wpa_ie_len;
@@ -1316,38 +1369,14 @@ static int prism54_get_genie(struct net_
return 0;
}
-static int prism54_set_auth(struct net_device *ndev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
+static int
+prism54_set_auth(struct net_device *ndev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
struct iw_param *param = &wrqu->param;
- u32 mlmelevel = 0, authen = 0, dot1x = 0;
- u32 exunencrypt = 0, privinvoked = 0, wpa = 0;
- u32 old_wpa;
- int ret = 0;
- union oid_res_t r;
-
- if (islpci_get_state(priv) < PRV_STATE_INIT)
- return 0;
-
- /* first get the flags */
- down_write(&priv->mib_sem);
- wpa = old_wpa = priv->wpa;
- up_write(&priv->mib_sem);
- ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
- authen = r.u;
- ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
- privinvoked = r.u;
- ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
- exunencrypt = r.u;
- ret = mgt_get_request(priv, DOT11_OID_DOT1XENABLE, 0, NULL, &r);
- dot1x = r.u;
- ret = mgt_get_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, NULL, &r);
- mlmelevel = r.u;
-
- if (ret < 0)
- goto out;
+ u32 set = 0;
+ int rvalue = 0;
switch (param->flags & IW_AUTH_INDEX) {
case IW_AUTH_CIPHER_PAIRWISE:
@@ -1355,103 +1384,72 @@ static int prism54_set_auth(struct net_d
case IW_AUTH_KEY_MGMT:
break;
- case IW_AUTH_WPA_ENABLED:
- /* Do the same thing as IW_AUTH_WPA_VERSION */
- if (param->value) {
- wpa = 1;
- privinvoked = 1; /* For privacy invoked */
- exunencrypt = 1; /* Filter out all unencrypted frames */
- dot1x = 0x01; /* To enable eap filter */
- mlmelevel = DOT11_MLME_EXTENDED;
- authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
- } else {
- wpa = 0;
- privinvoked = 0;
- exunencrypt = 0; /* Do not filter un-encrypted data */
- dot1x = 0;
- mlmelevel = DOT11_MLME_AUTO;
- }
- break;
-
case IW_AUTH_WPA_VERSION:
- if (param->value & IW_AUTH_WPA_VERSION_DISABLED) {
- wpa = 0;
- privinvoked = 0;
- exunencrypt = 0; /* Do not filter un-encrypted data */
- dot1x = 0;
- mlmelevel = DOT11_MLME_AUTO;
- } else {
- if (param->value & IW_AUTH_WPA_VERSION_WPA)
- wpa = 1;
- else if (param->value & IW_AUTH_WPA_VERSION_WPA2)
- wpa = 2;
- privinvoked = 1; /* For privacy invoked */
- exunencrypt = 1; /* Filter out all unencrypted frames */
- dot1x = 0x01; /* To enable eap filter */
- mlmelevel = DOT11_MLME_EXTENDED;
- authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
- }
+ if (set & IW_AUTH_WPA_VERSION_WPA)
+ set = 1;
+ if (set & IW_AUTH_WPA_VERSION_WPA2)
+ set |= 2;
+ case IW_AUTH_WPA_ENABLED:
+ if (!set)
+ set = param->value ? 3 : 0;
+ rvalue = prism54_set_wpa(ndev, info, &set, extra);
break;
case IW_AUTH_RX_UNENCRYPTED_EAPOL:
- dot1x = param->value ? 1 : 0;
+ set = param->value ? 1 : 0;
+ rvalue = mgt_set_request(priv, DOT11_OID_DOT1XENABLE,
+ 0, &set);
break;
case IW_AUTH_PRIVACY_INVOKED:
- privinvoked = param->value ? 1 : 0;
+ set = param->value ? 1 : 0;
+ rvalue = mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED,
+ 0, &set);
+ break;
case IW_AUTH_DROP_UNENCRYPTED:
- exunencrypt = param->value ? 1 : 0;
+ set = param->value ? 1 : 0;
+ rvalue = mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED,
+ 0, &set);
break;
case IW_AUTH_80211_AUTH_ALG:
- if (param->value & IW_AUTH_ALG_SHARED_KEY) {
- /* Only WEP uses _SK and _BOTH */
- if (wpa > 0) {
- ret = -EINVAL;
- goto out;
- }
- authen = DOT11_AUTH_SK;
- } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
- authen = DOT11_AUTH_OS;
- } else {
- ret = -EINVAL;
- goto out;
+ switch (param->value) {
+ case IW_AUTH_ALG_OPEN_SYSTEM:
+ set = DOT11_AUTH_OS;
+ break;
+ case IW_AUTH_ALG_SHARED_KEY:
+ set = DOT11_AUTH_SK;
+ break;
+ default:
+ return -EINVAL;
+ break;
}
+ rvalue = mgt_set_request(priv, DOT11_OID_AUTHENABLE,
+ 0, &set);
break;
default:
- return -EOPNOTSUPP;
+ rvalue = -EOPNOTSUPP;
+ break;
}
- /* Set all the values */
- down_write(&priv->mib_sem);
- priv->wpa = wpa;
- up_write(&priv->mib_sem);
- mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
- mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &privinvoked);
- mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0, &exunencrypt);
- mgt_set_request(priv, DOT11_OID_DOT1XENABLE, 0, &dot1x);
- mgt_set_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, &mlmelevel);
-
-out:
- return ret;
+ return rvalue;
}
-static int prism54_get_auth(struct net_device *ndev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
+static int
+prism54_get_auth(struct net_device *ndev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
struct iw_param *param = &wrqu->param;
- u32 wpa = 0;
- int ret = 0;
union oid_res_t r;
+ u32 wpa = 0;
+ int rvalue = 0;
if (islpci_get_state(priv) < PRV_STATE_INIT)
return 0;
- /* first get the flags */
down_write(&priv->mib_sem);
wpa = priv->wpa;
up_write(&priv->mib_sem);
@@ -1463,272 +1461,287 @@ static int prism54_get_auth(struct net_d
/*
* wpa_supplicant will control these internally
*/
- ret = -EOPNOTSUPP;
- break;
+ param->value = 0;
+ return -EOPNOTSUPP;
+ break;
case IW_AUTH_WPA_VERSION:
- switch (wpa) {
- case 1:
- param->value = IW_AUTH_WPA_VERSION_WPA;
- break;
- case 2:
- param->value = IW_AUTH_WPA_VERSION_WPA2;
- break;
- case 0:
- default:
+ if (!wpa)
param->value = IW_AUTH_WPA_VERSION_DISABLED;
- break;
- }
+ if (wpa & 1)
+ param->value = IW_AUTH_WPA_VERSION_WPA;
+ if (wpa & 2)
+ param->value |= IW_AUTH_WPA_VERSION_WPA2;
+
break;
case IW_AUTH_DROP_UNENCRYPTED:
- ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
- if (ret >= 0)
- param->value = r.u > 0 ? 1 : 0;
+ rvalue = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED,
+ 0, NULL, &r);
+ param->value = r.u;
break;
case IW_AUTH_80211_AUTH_ALG:
- ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
- if (ret >= 0) {
- switch (r.u) {
- case DOT11_AUTH_OS:
- param->value = IW_AUTH_ALG_OPEN_SYSTEM;
- break;
- case DOT11_AUTH_BOTH:
- case DOT11_AUTH_SK:
- param->value = IW_AUTH_ALG_SHARED_KEY;
- case DOT11_AUTH_NONE:
- default:
- param->value = 0;
- break;
- }
+ rvalue = mgt_get_request(priv, DOT11_OID_AUTHENABLE,
+ 0, NULL, &r);
+
+ switch (r.u) {
+ case DOT11_AUTH_OS:
+ param->value = IW_AUTH_ALG_OPEN_SYSTEM;
+ break;
+ case DOT11_AUTH_BOTH:
+ case DOT11_AUTH_SK:
+ param->value = IW_AUTH_ALG_SHARED_KEY;
+ break;
+ default:
+ param->value = 0;
+ rvalue = -EOPNOTSUPP;
+ break;
}
break;
case IW_AUTH_WPA_ENABLED:
- param->value = wpa > 0 ? 1 : 0;
+ param->value = wpa ? 0 : 1;
break;
case IW_AUTH_RX_UNENCRYPTED_EAPOL:
- ret = mgt_get_request(priv, DOT11_OID_DOT1XENABLE, 0, NULL, &r);
- if (ret >= 0)
- param->value = r.u > 0 ? 1 : 0;
+ rvalue = mgt_get_request(priv, DOT11_OID_DOT1XENABLE,
+ 0, NULL, &r);
+ param->value = r.u;
break;
case IW_AUTH_PRIVACY_INVOKED:
- ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
- if (ret >= 0)
- param->value = r.u > 0 ? 1 : 0;
+ rvalue = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED,
+ 0, NULL, &r);
+ param->value = r.u;
break;
default:
return -EOPNOTSUPP;
+ break;
}
- return ret;
+
+ return 0;
}
-static int prism54_set_encodeext(struct net_device *ndev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+static int
+prism54_set_encodeext(struct net_device *ndev, struct iw_request_info *info,
+ struct iw_point *dwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
- struct iw_point *encoding = &wrqu->encoding;
- struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- int idx, alg = ext->alg, set_key = 1;
+ struct iw_encode_ext *enc = (struct iw_encode_ext *)extra;
+ struct obj_stakey* key;
union oid_res_t r;
- int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0;
- int ret = 0;
-
- if (islpci_get_state(priv) < PRV_STATE_INIT)
- return 0;
-
- /* Determine and validate the key index */
- idx = (encoding->flags & IW_ENCODE_INDEX) - 1;
- if (idx) {
- if (idx < 0 || idx > 3)
- return -EINVAL;
- } else {
- ret = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
- if (ret < 0)
- goto out;
- idx = r.u;
- }
-
- if (encoding->flags & IW_ENCODE_DISABLED)
- alg = IW_ENCODE_ALG_NONE;
+ int index, key_type, keyop = DOT11_KEYOP_SET_KEY;
+ int ret = -EINVAL;
- if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
- /* Only set transmit key index here, actual
- * key is set below if needed.
- */
- ret = mgt_set_request(priv, DOT11_OID_DEFKEYID, 0, &idx);
- set_key = ext->key_len > 0 ? 1 : 0;
- }
+ if ((enc->key_len > (dwrq->length - sizeof(*enc))) ||
+ (enc->addr.sa_family != ARPHRD_ETHER))
+ return -EINVAL;
- if (set_key) {
- struct obj_key key = { DOT11_PRIV_WEP, 0, "" };
- switch (alg) {
+ switch (enc->alg) {
case IW_ENCODE_ALG_NONE:
+ key_type = DOT11_PRIV_WEP;
+ keyop = DOT11_KEYOP_REMOVE_KEY;
break;
case IW_ENCODE_ALG_WEP:
- if (ext->key_len > KEY_SIZE_WEP104) {
- ret = -EINVAL;
- goto out;
- }
- if (ext->key_len > KEY_SIZE_WEP40)
- key.length = KEY_SIZE_WEP104;
- else
- key.length = KEY_SIZE_WEP40;
+ key_type = DOT11_PRIV_WEP;
break;
case IW_ENCODE_ALG_TKIP:
- if (ext->key_len > KEY_SIZE_TKIP) {
- ret = -EINVAL;
- goto out;
- }
- key.type = DOT11_PRIV_TKIP;
- key.length = KEY_SIZE_TKIP;
+ key_type = DOT11_PRIV_TKIP;
+ break;
default:
- return -EINVAL;
- }
-
- if (key.length) {
- memset(key.key, 0, sizeof(key.key));
- memcpy(key.key, ext->key, ext->key_len);
- ret = mgt_set_request(priv, DOT11_OID_DEFKEYX, idx,
- &key);
- if (ret < 0)
- goto out;
- }
+ return -EOPNOTSUPP;
}
- /* Read the flags */
- if (encoding->flags & IW_ENCODE_DISABLED) {
- /* Encoding disabled,
- * authen = DOT11_AUTH_OS;
- * invoke = 0;
- * exunencrypt = 0; */
- }
- if (encoding->flags & IW_ENCODE_OPEN) {
- /* Encode but accept non-encoded packets. No auth */
- invoke = 1;
- }
- if (encoding->flags & IW_ENCODE_RESTRICTED) {
- /* Refuse non-encoded packets. Auth */
- authen = DOT11_AUTH_BOTH;
- invoke = 1;
- exunencrypt = 1;
+ index = (dwrq->flags & IW_ENCODE_INDEX);
+ if ((index < 0) || (index > 3)) {
+ /* no index provided, so get the current one */
+ ret = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
+ if (ret)
+ return ret;
+ index = r.u;
}
- /* do the change if requested */
- if (encoding->flags & IW_ENCODE_MODE) {
- ret = mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0,
- &authen);
- ret = mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0,
- &invoke);
- ret = mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0,
- &exunencrypt);
+ key = kzalloc(sizeof(*key) + enc->key_len, GFP_KERNEL);
+ if (!key)
+ return -ENOMEM;
+
+ key->type = key_type;
+ key->length = enc->key_len;
+ key->keyid = index;
+ key->reserved = keyop;
+ if (!(enc->ext_flags & IW_ENCODE_EXT_GROUP_KEY))
+ key->options = DOT11_STAKEY_OPTION_DEFAULTKEY;
+ else
+ key->options = DOT11_STAKEY_OPTION_GROUPKEY;
+
+ memcpy(key->key, enc->key, key->length);
+ memcpy(key->address, enc->addr.sa_data, ETH_ALEN);
+
+ ret = mgt_set_request(priv, DOT11_OID_STAKEY, 0, key);
+ kfree(key);
+ if (ret)
+ return ret;
+
+ if (enc->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
+ struct obj_stasc *stasc;
+ stasc = kzalloc(sizeof(*stasc), GFP_KERNEL);
+ if (!stasc)
+ return -ENOMEM;
+ memcpy(stasc->address, enc->addr.sa_data, ETH_ALEN);
+ stasc->keyid = index;
+ stasc->tx_sc = 1;
+ memcpy(stasc->sc, enc->rx_seq, 6);
+ ret = mgt_set_request(priv, DOT11_OID_STASC, 0, stasc);
+ kfree(stasc);
+ if (ret)
+ return ret;
}
-out:
+ if (dwrq->flags & IW_ENCODE_MODE)
+ ret = prism54_set_auth_alg(priv, dwrq->flags);
+
return ret;
}
-
-static int prism54_get_encodeext(struct net_device *ndev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+static int
+prism54_get_encodeext(struct net_device *ndev,
+ struct iw_request_info *info, struct iw_point *dwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
- struct iw_point *encoding = &wrqu->encoding;
- struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- int idx, max_key_len;
+ struct iw_encode_ext *enc = (struct iw_encode_ext *)extra;
+ struct obj_stasc *stasc;
union oid_res_t r;
- int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0, wpa = 0;
- int ret = 0;
+ int index;
+ int ret = -EINVAL;
+ int max_key_len;
- if (islpci_get_state(priv) < PRV_STATE_INIT)
- return 0;
-
- /* first get the flags */
- ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
- authen = r.u;
- ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
- invoke = r.u;
- ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
- exunencrypt = r.u;
- if (ret < 0)
- goto out;
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
- max_key_len = encoding->length - sizeof(*ext);
+ max_key_len = dwrq->length - sizeof(*enc);
if (max_key_len < 0)
return -EINVAL;
- idx = (encoding->flags & IW_ENCODE_INDEX) - 1;
- if (idx) {
- if (idx < 0 || idx > 3)
- return -EINVAL;
- } else {
+ memset(enc, 0, sizeof(*enc));
+
+ if (islpci_get_state(priv) < PRV_STATE_INIT) {
+ dwrq->flags = IW_ENCODE_DISABLED;
+ return 0;
+ }
+
+ index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
+ if ((index < 0) || (index > 3)) {
+ /* no index provided, so get the current one */
ret = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
- if (ret < 0)
- goto out;
- idx = r.u;
+ if (ret)
+ return ret;
+ index = r.u;
}
- encoding->flags = idx + 1;
- memset(ext, 0, sizeof(*ext));
+ if (enc->addr.sa_family != ARPHRD_ETHER) {
+ /* no "per-station key" */
+ struct obj_key *key;
+ ret = mgt_get_request(priv, DOT11_OID_DEFKEYX, index, NULL, &r);
+ key = r.ptr;
+ if (ret) {
+ kfree(key);
+ return ret;
+ }
- switch (authen) {
- case DOT11_AUTH_BOTH:
- case DOT11_AUTH_SK:
- wrqu->encoding.flags |= IW_ENCODE_RESTRICTED;
- case DOT11_AUTH_OS:
- default:
- wrqu->encoding.flags |= IW_ENCODE_OPEN;
+ if (key->length > max_key_len) {
+ kfree(key);
+ return -E2BIG;
+ }
+
+ enc->key_len = key->length;
+ switch (key->type) {
+ case DOT11_PRIV_WEP:
+ enc->alg = IW_ENCODE_ALG_WEP;
+ break;
+ case DOT11_PRIV_TKIP:
+ enc->alg = IW_ENCODE_ALG_TKIP;
break;
- }
+ default:
+ kfree(key);
+ return -EIO;
+ break;
+ }
- down_write(&priv->mib_sem);
- wpa = priv->wpa;
- up_write(&priv->mib_sem);
+ dwrq->flags |= IW_ENCODE_ENABLED;
+ memcpy(enc->key, key->key, enc->key_len);
+ dwrq->flags |= index +1;
+ return ret;
- if (authen == DOT11_AUTH_OS && !exunencrypt && !invoke && !wpa) {
- /* No encryption */
- ext->alg = IW_ENCODE_ALG_NONE;
- ext->key_len = 0;
- wrqu->encoding.flags |= IW_ENCODE_DISABLED;
- } else {
- struct obj_key *key;
+ }
+ else {
+ /* no "per-station key" */
+ struct obj_stakey *key;
+ key = kzalloc(sizeof(*key), GFP_KERNEL);
+ if (!key)
+ return -ENOMEM;
+
+ memcpy(key->address, enc->addr.sa_data, ETH_ALEN);
+ key->keyid = index;
+ ret = mgt_get_request(priv, DOT11_OID_STAKEY, 0, (void*)key, &r);
+ kfree(key);
+ key = (struct obj_stakey*)r.ptr;
+ if (ret) {
+ kfree(key);
+ return ret;
+ }
- ret = mgt_get_request(priv, DOT11_OID_DEFKEYX, idx, NULL, &r);
- if (ret < 0)
- goto out;
- key = r.ptr;
- if (max_key_len < key->length) {
- ret = -E2BIG;
- goto out;
+ if (key->length > max_key_len) {
+ kfree(key);
+ return -EINVAL;
}
- memcpy(ext->key, key->key, key->length);
- ext->key_len = key->length;
switch (key->type) {
- case DOT11_PRIV_TKIP:
- ext->alg = IW_ENCODE_ALG_TKIP;
+ case DOT11_PRIV_WEP:
+ enc->alg = IW_ENCODE_ALG_WEP;
break;
- default:
- case DOT11_PRIV_WEP:
- ext->alg = IW_ENCODE_ALG_WEP;
+ case DOT11_PRIV_TKIP:
+ enc->alg = IW_ENCODE_ALG_TKIP;
+ break;
+ default:
+ kfree(key);
+ return -EIO;
break;
}
- wrqu->encoding.flags |= IW_ENCODE_ENABLED;
+
+ enc->key_len = key->length;
+ dwrq->flags = index + 1;
+ memcpy(enc->key, key->key, key->length);
+ kfree(key);
+
+ /* add replay counter */
+ stasc = kzalloc(sizeof(*stasc), GFP_KERNEL);
+ if (!stasc)
+ return -ENOMEM;
+
+ memcpy(stasc->address, enc->addr.sa_data, ETH_ALEN);
+ stasc->keyid = index;
+ stasc->tx_sc = 1;
+ ret = mgt_get_request(priv, DOT11_OID_STASC, 0, (void*)stasc, &r);
+ kfree(stasc);
+ stasc = (struct obj_stasc*)r.ptr;
+ if (ret) {
+ kfree(stasc);
+ return ret;
+ }
+
+ memset(enc->tx_seq, 0, IW_ENCODE_SEQ_MAX_SIZE);
+ // prism's FW has only a 6 byte wide RSC!
+ memcpy(enc->tx_seq, stasc->sc, IW_ENCODE_SEQ_MAX_SIZE - 2);
+ enc->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID;
+ kfree(stasc);
+
}
-out:
return ret;
}
-
static int
prism54_reset(struct net_device *ndev, struct iw_request_info *info,
__u32 * uwrq, char *extra)
@@ -2030,14 +2043,12 @@ 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 " MAC_FMT " [%2.2x %2.2X %4.4X]",
str,
((priv->iw_mode == IW_MODE_MASTER) ? "from" : "to"),
- a[0], a[1], a[2], a[3], a[4], a[5],
- (error ? (mlme->code ? " : REJECTED " : " : ACCEPTED ")
- : ""), mlme->code);
+ MAC_ARG(mlme->address),
+ mlme->state, mlme->code, mlme->id);
BUG_ON(n > IW_CUSTOM_MAX);
*length = n;
}
@@ -2103,12 +2114,6 @@ struct ieee80211_beacon_phdr {
u16 capab_info;
} __attribute__ ((packed));
-#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)
@@ -2140,10 +2145,9 @@ prism54_wpa_bss_ie_add(islpci_private *p
struct islpci_bss_wpa_ie, list);
list_del(&bss->list);
} else {
- bss = kmalloc(sizeof (*bss), GFP_ATOMIC);
+ bss = kzalloc(sizeof(*bss), GFP_ATOMIC);
if (bss != NULL) {
priv->num_bss_wpa++;
- memset(bss, 0, sizeof (*bss));
}
}
if (bss != NULL) {
@@ -2157,8 +2161,8 @@ prism54_wpa_bss_ie_add(islpci_private *p
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 " MAC_FMT
+ "\n", MAC_ARG(bssid));
}
/* expire old entries from WPA list */
@@ -2220,6 +2224,8 @@ prism54_wpa_bss_ie_clean(islpci_private
}
}
+static u8 wpa_oid[4] = { 0x00, 0x50, 0xf2, 1 };
+
static void
prism54_process_bss_data(islpci_private *priv, u32 oid, u8 *addr,
u8 *payload, size_t len)
@@ -2235,11 +2241,16 @@ prism54_process_bss_data(islpci_private
end = payload + len;
while (pos < end) {
if (pos + 2 + pos[1] > end) {
- printk(KERN_DEBUG "Parsing Beacon/ProbeResp failed "
- "for " MACSTR "\n", MAC2STR(addr));
+ printk(KERN_DEBUG "Parsing %s failed "
+ "for " MAC_FMT "\n", (oid == DOT11_OID_BEACON ? "Beacon" : "ProbeResp"), MAC_ARG(addr));
return;
}
- if (pos[0] == WLAN_EID_GENERIC && pos[1] >= 4 &&
+ /* Don't forget RSN/WPA2 ! */
+ if (pos[0] == MFIE_TYPE_RSN && pos[1] > 4) {
+ prism54_wpa_bss_ie_add(priv, addr, pos, pos[1] + 2);
+ return;
+ }
+ if (pos[0] == MFIE_TYPE_GENERIC && pos[1] >= 4 &&
memcmp(pos + 2, wpa_oid, 4) == 0) {
prism54_wpa_bss_ie_add(priv, addr, pos, pos[1] + 2);
return;
@@ -2264,39 +2275,81 @@ handle_request(islpci_private *priv, str
}
static int
+prism54_process_sta_trap(islpci_private *priv, enum oid_num_t oid,
+ struct obj_mlmeex* mlmeex)
+{
+ struct obj_mlme *mlme = (struct obj_mlme*)mlmeex;
+ int ret = 0;
+
+ switch (oid) {
+ case DOT11_OID_DEAUTHENTICATEEX:
+ send_formatted_event(priv, "DeAuthenticate request",
+ mlme, 0);
+ break;
+
+ case DOT11_OID_AUTHENTICATEEX:
+ if (prism54_mac_accept(&priv->acl, mlmeex->address) &&
+ (mlmeex->state == DOT11_STATE_AUTH)) {
+
+ mlmeex->state = DOT11_STATE_ASSOCING;
+ mlmeex->code = 0;
+ mlmeex->size = 0;
+ ret = mgt_set_request(priv, DOT11_OID_ASSOCIATEEX,
+ 0, mlmeex);
+ if (ret)
+ return ret;
+ }
+ if (mlmeex->code != 0)
+ send_formatted_event(priv, "Authenticate request",
+ mlme, 1);
+ break;
+
+ case DOT11_OID_DISASSOCIATEEX:
+ send_formatted_event(priv, "Disassociate request",
+ mlme, 0);
+ break;
+
+ case DOT11_OID_ASSOCIATEEX:
+ if (mlmeex->code)
+ send_formatted_event(priv, "Associate request",
+ mlme, 1);
+ break;
+
+ case DOT11_OID_REASSOCIATEEX:
+ if (mlmeex->code)
+ send_formatted_event(priv, "Reassociate request",
+ mlme, 1);
+ break;
+
+ default:
+ printk(KERN_INFO "%s: Unhandled OID %x, "
+ "please fill a bug-report!\n", priv->ndev->name, oid);
+ break;
+ }
+
+ return ret;
+}
+
+static int
prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
char *data)
{
struct obj_mlme *mlme = (struct obj_mlme *) data;
struct obj_mlmeex *mlmeex = (struct obj_mlmeex *) data;
- struct obj_mlmeex *confirm;
- u8 wpa_ie[MAX_WPA_IE_LEN];
- int wpa_ie_len;
- size_t len = 0; /* u16, better? */
- u8 *payload = NULL, *pos = NULL;
- int ret;
-
- /* I think all trapable objects are listed here.
- * Some oids have a EX version. The difference is that they are emitted
- * in DOT11_MLME_EXTENDED mode (set with DOT11_OID_MLMEAUTOLEVEL)
- * with more info.
- * The few events already defined by the wireless tools are not really
- * suited. We use the more flexible custom event facility.
- */
-
- if (oid >= DOT11_OID_BEACON) {
- len = mlmeex->size;
- payload = pos = mlmeex->data;
- }
+ int ret = 0;
/* I fear prism54_process_bss_data won't work with big endian data */
- if ((oid == DOT11_OID_BEACON) || (oid == DOT11_OID_PROBE))
- prism54_process_bss_data(priv, oid, mlmeex->address,
- payload, len);
mgt_le_to_cpu(isl_oid[oid].flags & OID_FLAG_TYPE, (void *) mlme);
switch (oid) {
+ case DOT11_OID_BEACON:
+ case DOT11_OID_PROBE:
+ if (priv->iw_mode != IW_MODE_MASTER
+ && mlmeex->state != DOT11_STATE_AUTHING)
+ prism54_process_bss_data(priv, oid, mlmeex->address,
+ mlmeex->data, mlmeex->size);
+ break;
case GEN_OID_LINKSTATE:
link_changed(priv->ndev, (u32) *data);
@@ -2329,163 +2382,12 @@ prism54_process_trap_helper(islpci_priva
send_formatted_event(priv, "ReAssociate request", mlme, 1);
break;
- case DOT11_OID_BEACON:
- send_formatted_event(priv,
- "Received a beacon from an unkown AP",
- mlme, 0);
- break;
-
- case DOT11_OID_PROBE:
- /* we received a probe from a client. */
- send_formatted_event(priv, "Received a probe from client", mlme,
- 0);
- break;
-
- /* Note : "mlme" is actually a "struct obj_mlmeex *" here, but this
- * is backward compatible layout-wise with "struct obj_mlme".
- */
-
- case DOT11_OID_DEAUTHENTICATEEX:
- send_formatted_event(priv, "DeAuthenticate request", mlme, 0);
- break;
-
- case DOT11_OID_AUTHENTICATEEX:
- handle_request(priv, mlme, oid);
- send_formatted_event(priv, "Authenticate request (ex)", mlme, 1);
-
- if (priv->iw_mode != IW_MODE_MASTER
- && mlmeex->state != DOT11_STATE_AUTHING)
- break;
-
- confirm = kmalloc(sizeof(struct obj_mlmeex) + 6, GFP_ATOMIC);
-
- 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]
- );
- confirm->id = -1; /* or mlmeex->id ? */
- confirm->state = 0; /* not used */
- confirm->code = 0;
- confirm->size = 6;
- confirm->data[0] = 0x00;
- confirm->data[1] = 0x00;
- confirm->data[2] = 0x02;
- confirm->data[3] = 0x00;
- confirm->data[4] = 0x00;
- confirm->data[5] = 0x00;
-
- ret = mgt_set_varlen(priv, DOT11_OID_ASSOCIATEEX, confirm, 6);
-
- kfree(confirm);
- if (ret)
- return ret;
- break;
-
- case DOT11_OID_DISASSOCIATEEX:
- send_formatted_event(priv, "Disassociate request (ex)", mlme, 0);
- break;
-
- case DOT11_OID_ASSOCIATEEX:
- handle_request(priv, mlme, oid);
- send_formatted_event(priv, "Associate request (ex)", mlme, 1);
-
- if (priv->iw_mode != IW_MODE_MASTER
- && mlmeex->state != DOT11_STATE_ASSOCING)
- break;
-
- confirm = kmalloc(sizeof(struct obj_mlmeex), GFP_ATOMIC);
-
- if (!confirm)
- break;
-
- memcpy(&confirm->address, mlmeex->address, ETH_ALEN);
-
- confirm->id = ((struct obj_mlmeex *)mlme)->id;
- confirm->state = 0; /* not used */
- confirm->code = 0;
-
- 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]
- );
- kfree(confirm);
- break;
- }
-
- 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;
-
- 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
- && mlmeex->state != DOT11_STATE_ASSOCING)
- break;
-
- confirm = kmalloc(sizeof(struct obj_mlmeex), GFP_ATOMIC);
-
- if (!confirm)
- break;
-
- memcpy(&confirm->address, mlmeex->address, ETH_ALEN);
-
- confirm->id = mlmeex->id;
- confirm->state = 0; /* not used */
- confirm->code = 0;
-
- 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]
- );
- kfree(confirm);
- break;
- }
-
- 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:
- return -EINVAL;
+ ret = prism54_process_sta_trap(priv, oid, mlmeex);
+ break;
}
- return 0;
+ return ret;
}
/*
@@ -2521,368 +2423,33 @@ prism54_set_mac_address(struct net_devic
return ret;
}
-/* Note: currently, use hostapd ioctl from the Host AP driver for WPA
- * support. This is to be replaced with Linux wireless extensions once they
- * get WPA support. */
-
-/* Note II: please leave all this together as it will be easier to remove later,
- * once wireless extensions add WPA support -mcgrof */
-
-/* PRISM54_HOSTAPD ioctl() cmd: */
-enum {
- PRISM2_SET_ENCRYPTION = 6,
- PRISM2_HOSTAPD_SET_GENERIC_ELEMENT = 12,
- PRISM2_HOSTAPD_MLME = 13,
- PRISM2_HOSTAPD_SCAN_REQ = 14,
-};
-
-#define PRISM54_SET_WPA SIOCIWFIRSTPRIV+12
-#define PRISM54_HOSTAPD SIOCIWFIRSTPRIV+25
-#define PRISM54_DROP_UNENCRYPTED SIOCIWFIRSTPRIV+26
-
-#define PRISM2_HOSTAPD_MAX_BUF_SIZE 1024
-#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)
- * used in ioctl() */
-#define HOSTAP_CRYPT_ALG_NAME_LEN 16
-
-struct prism2_hostapd_param {
- u32 cmd;
- u8 sta_addr[ETH_ALEN];
- union {
- struct {
- u8 alg[HOSTAP_CRYPT_ALG_NAME_LEN];
- u32 flags;
- u32 err;
- u8 idx;
- u8 seq[8]; /* sequence counter (set: RX, get: TX) */
- u16 key_len;
- u8 key[0];
- } crypt;
- struct {
- u8 len;
- u8 data[0];
- } generic_elem;
- struct {
-#define MLME_STA_DEAUTH 0
-#define MLME_STA_DISASSOC 1
- u16 cmd;
- u16 reason_code;
- } mlme;
- struct {
- u8 ssid_len;
- u8 ssid[32];
- } scan_req;
- } u;
-};
-
-
-static int
-prism2_ioctl_set_encryption(struct net_device *dev,
- struct prism2_hostapd_param *param,
- int param_len)
-{
- islpci_private *priv = netdev_priv(dev);
- int rvalue = 0, force = 0;
- int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0;
- union oid_res_t r;
-
- /* with the new API, it's impossible to get a NULL pointer.
- * New version of iwconfig set the IW_ENCODE_NOKEY flag
- * when no key is given, but older versions don't. */
-
- if (param->u.crypt.key_len > 0) {
- /* we have a key to set */
- int index = param->u.crypt.idx;
- int current_index;
- struct obj_key key = { DOT11_PRIV_TKIP, 0, "" };
-
- /* get the current key index */
- rvalue = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
- current_index = r.u;
- /* Verify that the key is not marked as invalid */
- if (!(param->u.crypt.flags & IW_ENCODE_NOKEY)) {
- key.length = param->u.crypt.key_len > sizeof (param->u.crypt.key) ?
- sizeof (param->u.crypt.key) : param->u.crypt.key_len;
- memcpy(key.key, param->u.crypt.key, key.length);
- if (key.length == 32)
- /* we want WPA-PSK */
- key.type = DOT11_PRIV_TKIP;
- if ((index < 0) || (index > 3))
- /* no index provided use the current one */
- index = current_index;
-
- /* now send the key to the card */
- rvalue |=
- mgt_set_request(priv, DOT11_OID_DEFKEYX, index,
- &key);
- }
- /*
- * 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
- */
- if ((index == current_index) && (key.length > 0))
- force = 1;
- } else {
- int index = (param->u.crypt.flags & IW_ENCODE_INDEX) - 1;
- if ((index >= 0) && (index <= 3)) {
- /* we want to set the key index */
- rvalue |=
- mgt_set_request(priv, DOT11_OID_DEFKEYID, 0,
- &index);
- } else {
- if (!param->u.crypt.flags & IW_ENCODE_MODE) {
- /* we cannot do anything. Complain. */
- return -EINVAL;
- }
- }
- }
- /* now read the flags */
- if (param->u.crypt.flags & IW_ENCODE_DISABLED) {
- /* Encoding disabled,
- * authen = DOT11_AUTH_OS;
- * invoke = 0;
- * exunencrypt = 0; */
- }
- if (param->u.crypt.flags & IW_ENCODE_OPEN)
- /* Encode but accept non-encoded packets. No auth */
- invoke = 1;
- if ((param->u.crypt.flags & IW_ENCODE_RESTRICTED) || force) {
- /* Refuse non-encoded packets. Auth */
- authen = DOT11_AUTH_BOTH;
- invoke = 1;
- exunencrypt = 1;
- }
- /* do the change if requested */
- if ((param->u.crypt.flags & IW_ENCODE_MODE) || force) {
- rvalue |=
- mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
- rvalue |=
- mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &invoke);
- rvalue |=
- mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0,
- &exunencrypt);
- }
- return rvalue;
-}
-
-static int
-prism2_ioctl_set_generic_element(struct net_device *ndev,
- struct prism2_hostapd_param *param,
- int param_len)
-{
- islpci_private *priv = netdev_priv(ndev);
- int max_len, len, alen, ret=0;
- struct obj_attachment *attach;
-
- len = param->u.generic_elem.len;
- max_len = param_len - PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN;
- if (max_len < 0 || max_len < len)
- return -EINVAL;
-
- alen = sizeof(*attach) + len;
- attach = kmalloc(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
-
- /* Note: endianness is covered by mgt_set_varlen */
-
- attach->type = (WLAN_FC_TYPE_MGMT << 2) |
- (WLAN_FC_STYPE_ASSOC_REQ << 4);
- attach->id = -1;
- attach->size = len;
- memcpy(attach->data, param->u.generic_elem.data, len);
-
- ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach, len);
-
- if (ret == 0) {
- attach->type = (WLAN_FC_TYPE_MGMT << 2) |
- (WLAN_FC_STYPE_REASSOC_REQ << 4);
-
- ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach, len);
-
- if (ret == 0)
- printk(KERN_DEBUG "%s: WPA IE Attachment was set\n",
- ndev->name);
- }
-
- kfree(attach);
- return ret;
-
-}
-
-static int
-prism2_ioctl_mlme(struct net_device *dev, struct prism2_hostapd_param *param)
-{
- return -EOPNOTSUPP;
-}
-
-static int
-prism2_ioctl_scan_req(struct net_device *ndev,
- struct prism2_hostapd_param *param)
-{
- islpci_private *priv = netdev_priv(ndev);
- int i, rvalue;
- struct obj_bsslist *bsslist;
- u32 noise = 0;
- char *extra = "";
- char *current_ev = "foo";
- union oid_res_t r;
-
- if (islpci_get_state(priv) < PRV_STATE_INIT) {
- /* device is not ready, fail gently */
- return 0;
- }
-
- /* first get the noise value. We will use it to report the link quality */
- rvalue = mgt_get_request(priv, DOT11_OID_NOISEFLOOR, 0, NULL, &r);
- noise = r.u;
-
- /* Ask the device for a list of known bss. We can report at most
- * IW_MAX_AP=64 to the range struct. 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 < min(IW_MAX_AP, (int) bsslist->nr); i++)
- current_ev = prism54_translate_bss(ndev, current_ev,
- extra + IW_SCAN_MAX_DATA,
- &(bsslist->bsslist[i]),
- noise);
- kfree(bsslist);
-
- return rvalue;
-}
-
-static int
-prism54_hostapd(struct net_device *ndev, struct iw_point *p)
-{
- struct prism2_hostapd_param *param;
- int ret = 0;
- u32 uwrq;
-
- printk(KERN_DEBUG "prism54_hostapd - len=%d\n", p->length);
- if (p->length < sizeof(struct prism2_hostapd_param) ||
- p->length > PRISM2_HOSTAPD_MAX_BUF_SIZE || !p->pointer)
- return -EINVAL;
-
- param = (struct prism2_hostapd_param *) kmalloc(p->length, GFP_KERNEL);
- if (param == NULL)
- return -ENOMEM;
-
- if (copy_from_user(param, p->pointer, p->length)) {
- kfree(param);
- return -EFAULT;
- }
-
- switch (param->cmd) {
- case PRISM2_SET_ENCRYPTION:
- printk(KERN_DEBUG "%s: Caught WPA supplicant set encryption request\n",
- ndev->name);
- ret = prism2_ioctl_set_encryption(ndev, param, p->length);
- break;
- case PRISM2_HOSTAPD_SET_GENERIC_ELEMENT:
- printk(KERN_DEBUG "%s: Caught WPA supplicant set WPA IE request\n",
- ndev->name);
- ret = prism2_ioctl_set_generic_element(ndev, param,
- p->length);
- break;
- case PRISM2_HOSTAPD_MLME:
- printk(KERN_DEBUG "%s: Caught WPA supplicant MLME request\n",
- ndev->name);
- ret = prism2_ioctl_mlme(ndev, param);
- break;
- case PRISM2_HOSTAPD_SCAN_REQ:
- printk(KERN_DEBUG "%s: Caught WPA supplicant scan request\n",
- ndev->name);
- ret = prism2_ioctl_scan_req(ndev, param);
- break;
- case PRISM54_SET_WPA:
- printk(KERN_DEBUG "%s: Caught WPA supplicant wpa init request\n",
- ndev->name);
- uwrq = 1;
- ret = prism54_set_wpa(ndev, NULL, &uwrq, NULL);
- break;
- case PRISM54_DROP_UNENCRYPTED:
- printk(KERN_DEBUG "%s: Caught WPA drop unencrypted request\n",
- ndev->name);
-#if 0
- uwrq = 0x01;
- mgt_set(priv, DOT11_OID_EXUNENCRYPTED, &uwrq);
- down_write(&priv->mib_sem);
- mgt_commit(priv);
- up_write(&priv->mib_sem);
-#endif
- /* Not necessary, as set_wpa does it, should we just do it here though? */
- ret = 0;
- break;
- default:
- printk(KERN_DEBUG "%s: Caught a WPA supplicant request that is not supported\n",
- ndev->name);
- ret = -EOPNOTSUPP;
- break;
- }
-
- if (ret == 0 && copy_to_user(p->pointer, param, p->length))
- ret = -EFAULT;
-
- kfree(param);
-
- return ret;
-}
-
static int
prism54_set_wpa(struct net_device *ndev, struct iw_request_info *info,
__u32 * uwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
- u32 mlme, authen, dot1x, filter, wep;
+ u32 mlme, dot1x;
if (islpci_get_state(priv) < PRV_STATE_INIT)
return 0;
- wep = 1; /* For privacy invoked */
- filter = 1; /* Filter out all unencrypted frames */
- dot1x = 0x01; /* To enable eap filter */
- mlme = DOT11_MLME_EXTENDED;
- authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
+ dot1x = 0; // disable global filtering
+ mlme = DOT11_MLME_AUTO;
down_write(&priv->mib_sem);
priv->wpa = *uwrq;
- switch (priv->wpa) {
- default:
- case 0: /* Clears/disables WPA and friends */
- wep = 0;
- filter = 0; /* Do not filter un-encrypted data */
- dot1x = 0;
- mlme = DOT11_MLME_AUTO;
- printk("%s: Disabling WPA\n", ndev->name);
- break;
- case 2:
- case 1: /* WPA */
- printk("%s: Enabling WPA\n", ndev->name);
- break;
+ if (priv->wpa) {
+ if (priv->iw_mode == IW_MODE_MASTER)
+ dot1x = 1;
+ mlme = DOT11_MLME_EXTENDED;
}
up_write(&priv->mib_sem);
- mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
- mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &wep);
- mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0, &filter);
mgt_set_request(priv, DOT11_OID_DOT1XENABLE, 0, &dot1x);
mgt_set_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, &mlme);
- return 0;
+ return prism54_set_auth_alg(priv, IW_ENCODE_OPEN);
}
static int
@@ -2890,7 +2457,9 @@ prism54_get_wpa(struct net_device *ndev,
__u32 * uwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
+ down_write(&priv->mib_sem);
*uwrq = priv->wpa;
+ up_write(&priv->mib_sem);
return 0;
}
@@ -3025,6 +2594,80 @@ prism54_set_spy(struct net_device *ndev,
return iw_handler_set_spy(ndev, info, uwrq, extra);
}
+static int
+prism54_send_mlme(struct net_device *ndev, struct iw_request_info *info,
+ struct iw_point *dwrq, char *extra)
+{
+ islpci_private *priv = netdev_priv(ndev);
+ struct iw_mlme *iwmlme;
+ struct obj_mlme mlme;
+ struct obj_sta *sta;
+ union oid_res_t r;
+ int ret = 0;
+
+ if (dwrq->length != sizeof(*iwmlme))
+ return -EINVAL;
+
+ iwmlme = (struct iw_mlme*)extra;
+
+ if (iwmlme->addr.sa_family != ARPHRD_ETHER)
+ return -EINVAL;
+
+ /* get STA/AP Id.
+ or the card will BROADCAST the packet! */
+
+ sta = (struct obj_sta*)kzalloc(sizeof(*sta), GFP_KERNEL);
+ if (!sta)
+ return -ENOMEM;
+
+ memcpy(sta->address, iwmlme->addr.sa_data, ETH_ALEN);
+ ret = mgt_get_request(priv, DOT11_OID_CLIENTFIND, 0, sta, &r);
+ kfree(sta);
+
+ if (ret) {
+ sta = r.ptr;
+ memcpy(mlme.address, iwmlme->addr.sa_data, ETH_ALEN);
+
+ if (sta->node >= 1)
+ mlme.id = sta->node;
+ else
+ mlme.id = -1;
+ } else
+ /* use broadcast id */
+ mlme.id = -1;
+
+ mlme.code = iwmlme->reason_code;
+
+ kfree(r.ptr);
+ switch (iwmlme->cmd) {
+ case IW_MLME_DEAUTH:
+ mlme.state = DOT11_STATE_NONE;
+ return mgt_set_request(priv, DOT11_OID_DEAUTHENTICATE,
+ 0, &mlme);
+ break;
+ case IW_MLME_DISASSOC:
+ mlme.state = DOT11_STATE_NONE;
+ return mgt_set_request(priv, DOT11_OID_DISASSOCIATE,
+ 0, &mlme);
+ break;
+#if 0
+ /* not in WEXT yet */
+ case IW_MLME_AUTH:
+ mlme.state = DOT11_STATE_AUTH;
+ return mgt_set_request(priv, DOT11_OID_AUTHENTICATE,
+ 0, &mlme);
+ break;
+ case IW_MLME_ASSOC:
+ mlme.state = DOT11_STATE_ASSOC;
+ return mgt_set_request(priv, DOT11_OID_ASSOCIATE,
+ 0, &mlme);
+ break;
+#endif
+ }
+
+ return -EOPNOTSUPP;
+}
+
static const iw_handler prism54_handler[] = {
(iw_handler) prism54_commit, /* SIOCSIWCOMMIT */
(iw_handler) prism54_get_name, /* SIOCGIWNAME */
@@ -3042,13 +2685,13 @@ static const iw_handler prism54_handler[
(iw_handler) NULL, /* SIOCGIWPRIV */
(iw_handler) NULL, /* SIOCSIWSTATS */
(iw_handler) NULL, /* SIOCGIWSTATS */
- prism54_set_spy, /* SIOCSIWSPY */
+ (iw_handler) prism54_set_spy, /* SIOCSIWSPY */
iw_handler_get_spy, /* SIOCGIWSPY */
iw_handler_set_thrspy, /* SIOCSIWTHRSPY */
iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
(iw_handler) prism54_set_wap, /* SIOCSIWAP */
(iw_handler) prism54_get_wap, /* SIOCGIWAP */
- (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) prism54_send_mlme, /* SIOCSIWMLME */
(iw_handler) NULL, /* SIOCGIWAPLIST depreciated */
(iw_handler) prism54_set_scan, /* SIOCSIWSCAN */
(iw_handler) prism54_get_scan, /* SIOCGIWSCAN */
@@ -3072,15 +2715,15 @@ static const iw_handler prism54_handler[
(iw_handler) prism54_get_encode, /* SIOCGIWENCODE */
(iw_handler) NULL, /* SIOCSIWPOWER */
(iw_handler) NULL, /* SIOCGIWPOWER */
- NULL, /* -- hole -- */
- NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
(iw_handler) prism54_set_genie, /* SIOCSIWGENIE */
(iw_handler) prism54_get_genie, /* SIOCGIWGENIE */
(iw_handler) prism54_set_auth, /* SIOCSIWAUTH */
(iw_handler) prism54_get_auth, /* SIOCGIWAUTH */
- (iw_handler) prism54_set_encodeext, /* SIOCSIWENCODEEXT */
- (iw_handler) prism54_get_encodeext, /* SIOCGIWENCODEEXT */
- NULL, /* SIOCSIWPMKSA */
+ (iw_handler) prism54_set_encodeext, /* SIOCSIWENCODEEXT */
+ (iw_handler) prism54_get_encodeext, /* SIOCGIWENCODEEXT */
+ (iw_handler) NULL /* SIOCSIWPMKSA */
};
/* The low order bit identify a SET (0) or a GET (1) ioctl. */
@@ -3259,14 +2902,5 @@ const struct iw_handler_def prism54_hand
int
prism54_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
{
- struct iwreq *wrq = (struct iwreq *) rq;
- int ret = -1;
- switch (cmd) {
- case PRISM54_HOSTAPD:
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- ret = prism54_hostapd(ndev, &wrq->u.data);
- return ret;
- }
return -EOPNOTSUPP;
}
diff --git a/drivers/net/wireless/prism54/isl_ioctl.h b/drivers/net/wireless/prism54/isl_ioctl.h
index e8183d3..8322133 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.h
+++ b/drivers/net/wireless/prism54/isl_ioctl.h
@@ -1,4 +1,5 @@
/*
+ *
* Copyright (C) 2002 Intersil Americas Inc.
* (C) 2003 Aurelien Alleaume <slts@free.fr>
* (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
@@ -21,12 +22,11 @@
#ifndef _ISL_IOCTL_H
#define _ISL_IOCTL_H
+#include <net/iw_handler.h> /* New driver API */
#include "islpci_mgt.h"
#include "islpci_dev.h"
-#include <net/iw_handler.h> /* New driver API */
-
-#define SUPPORTED_WIRELESS_EXT 19
+#define SUPPORTED_WIRELESS_EXT 21
void prism54_mib_init(islpci_private *);
diff --git a/drivers/net/wireless/prism54/isl_oid.h b/drivers/net/wireless/prism54/isl_oid.h
index b7534c2..88b24d6 100644
--- a/drivers/net/wireless/prism54/isl_oid.h
+++ b/drivers/net/wireless/prism54/isl_oid.h
@@ -2,6 +2,7 @@
* Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
* Copyright (C) 2004 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
* Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
+ * Copyright (C) 2006 Christian Lamparter <chunkeey@web.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,29 +27,67 @@
* with the device firmware
*/
+#define MAX_KEY_LEN 32
+
struct obj_ssid {
u8 length;
- char octets[33];
+ u8 octets[IW_ESSID_MAX_SIZE + 1];
} __attribute__ ((packed));
+enum dot11_priv_t {
+ DOT11_PRIV_WEP = 0,
+ DOT11_PRIV_TKIP = 1
+};
+
struct obj_key {
u8 type; /* dot11_priv_t */
u8 length;
- char key[32];
+ u8 key[MAX_KEY_LEN];
} __attribute__ ((packed));
+enum dot11_stakey_opt_t {
+ DOT11_STAKEY_OPTION_GROUPKEY = 0x0000,
+ DOT11_STAKEY_OPTION_DEFAULTKEY = 0x0001
+};
+
+enum dot11_keyop_t {
+ DOT11_KEYOP_SET_KEY = 0x0000,
+ DOT11_KEYOP_REMOVE_KEY = 0x0001
+};
+
+struct obj_stakey {
+ u8 address[ETH_ALEN];
+ u8 keyid;
+ u8 reserved; /* dot11_keyop_t */
+ u16 options; /* dot11_stakey_opt_t */
+ u8 type; /* dot11_priv_t */
+ u8 length;
+ u8 key[MAX_KEY_LEN];
+} __attribute__ ((packed));
+
+enum dot11_state_t {
+ DOT11_STATE_NONE = 0,
+ DOT11_STATE_AUTHING = 1,
+ DOT11_STATE_AUTH = 2,
+ DOT11_STATE_ASSOCING = 3,
+ DOT11_STATE_REASSOC = 4,
+ DOT11_STATE_ASSOC = 5,
+ DOT11_STATE_IBSS = 6,
+ DOT11_STATE_WDS = 7
+};
+
struct obj_mlme {
- u8 address[6];
+ u8 address[ETH_ALEN];
u16 id;
- u16 state;
- u16 code;
+ u16 state; /* dot11_state_t */
+ u16 code; /* WLAN_STATUS_ / WLAN_REASON_ */
} __attribute__ ((packed));
struct obj_mlmeex {
- u8 address[6];
+ u8 address[ETH_ALEN];
u16 id;
- u16 state;
- u16 code;
+ u16 state; /* dot11_state_t */
+ u16 code; /* WLAN_STATUS_ / WLAN_REASON_ */
u16 size;
u8 data[0];
} __attribute__ ((packed));
@@ -59,23 +98,23 @@ struct obj_buffer {
} __attribute__ ((packed));
struct obj_bss {
- u8 address[6];
+ u8 address[ETH_ALEN];
int:16; /* padding */
- char state;
- char reserved;
- short age;
+ u8 state; /* dot11_state_t */
+ u8 reserved;
+ u16 age;
- char quality;
- char rssi;
+ u8 quality;
+ u8 rssi;
struct obj_ssid ssid;
- short channel;
- char beacon_period;
- char dtim_period;
- short capinfo;
- short rates;
- short basic_rates;
+ u16 channel;
+ u8 beacon_period;
+ u8 dtim_period;
+ u16 capinfo; /* WLAN_CAPABILITY_ */
+ u16 rates;
+ u16 basic_rates;
int:16; /* padding */
} __attribute__ ((packed));
@@ -90,14 +129,33 @@ struct obj_frequencies {
} __attribute__ ((packed));
struct obj_attachment {
- char type;
- char reserved;
- short id;
- short size;
- char data[0];
+ u8 type; /* IEEE80211_STYPE_ */
+ u8 reserved;
+ u16 id;
+ u16 size;
+ u8 data[0];
} __attribute__((packed));
-/*
+struct obj_stasc {
+ u8 address[ETH_ALEN];
+ u8 keyid;
+ u8 tx_sc;
+ u8 sc[6];
+} __attribute__ ((packed));
+
+struct obj_sta {
+ u8 address[ETH_ALEN];
+ int:16;
+ u8 state; /* dot11_state_t */
+ u8 node; /* Station ID */
+ u16 age;
+ u8 reserved1;
+ u8 rssi;
+ u8 rate;
+ u8 reserved2;
+} __attribute__ ((packed));
+
+/*
* in case everything's ok, the inlined function below will be
* optimized away by the compiler...
*/
@@ -112,19 +170,12 @@ __bug_on_wrong_struct_sizes(void)
BUILD_BUG_ON(sizeof (struct obj_bss) != 60);
BUILD_BUG_ON(sizeof (struct obj_bsslist) != 4);
BUILD_BUG_ON(sizeof (struct obj_frequencies) != 2);
+ BUILD_BUG_ON(sizeof (struct obj_sta) != 16);
+ BUILD_BUG_ON(sizeof (struct obj_stasc) != 14);
+ BUILD_BUG_ON(sizeof (struct obj_stakey) != 44);
+ BUILD_BUG_ON(sizeof (struct obj_attachment) != 6);
}
-enum dot11_state_t {
- DOT11_STATE_NONE = 0,
- DOT11_STATE_AUTHING = 1,
- DOT11_STATE_AUTH = 2,
- DOT11_STATE_ASSOCING = 3,
-
- DOT11_STATE_ASSOC = 5,
- DOT11_STATE_IBSS = 6,
- DOT11_STATE_WDS = 7
-};
-
enum dot11_bsstype_t {
DOT11_BSSTYPE_NONE = 0,
DOT11_BSSTYPE_INFRA = 1,
@@ -145,11 +196,6 @@ enum dot11_mlme_t {
DOT11_MLME_EXTENDED = 2
};
-enum dot11_priv_t {
- DOT11_PRIV_WEP = 0,
- DOT11_PRIV_TKIP = 1
-};
-
/* Prism "Nitro" / Frameburst / "Packet Frame Grouping"
* Value is in microseconds. Represents the # microseconds
* the firmware will take to group frames before sending out then out
@@ -464,31 +510,32 @@ enum oid_num_t {
OID_NUM_LAST
};
-#define OID_FLAG_CACHED 0x80
-#define OID_FLAG_TYPE 0x7f
-
-#define OID_TYPE_U32 0x01
-#define OID_TYPE_SSID 0x02
-#define OID_TYPE_KEY 0x03
-#define OID_TYPE_BUFFER 0x04
-#define OID_TYPE_BSS 0x05
-#define OID_TYPE_BSSLIST 0x06
-#define OID_TYPE_FREQUENCIES 0x07
-#define OID_TYPE_MLME 0x08
-#define OID_TYPE_MLMEEX 0x09
-#define OID_TYPE_ADDR 0x0A
-#define OID_TYPE_RAW 0x0B
-#define OID_TYPE_ATTACH 0x0C
-
-/* OID_TYPE_MLMEEX is special because of a variable size field when sending.
- * Not yet implemented (not used in driver anyway).
- */
+enum oid_types_t {
+ OID_TYPE_U32 = 0x01,
+ OID_TYPE_SSID = 0x02,
+ OID_TYPE_KEY = 0x03,
+ OID_TYPE_BUFFER = 0x04,
+ OID_TYPE_BSS = 0x05,
+ OID_TYPE_BSSLIST = 0x06,
+ OID_TYPE_FREQUENCIES = 0x07,
+ OID_TYPE_MLME = 0x08,
+ OID_TYPE_MLMEEX = 0x09,
+ OID_TYPE_ADDR = 0x0A,
+ OID_TYPE_RAW = 0x0B,
+ OID_TYPE_ATTACH = 0x0C,
+ OID_TYPE_STASC = 0x0D,
+ OID_TYPE_STAKEY = 0x0E,
+ OID_TYPE_STAINFO = 0x0F,
+
+ OID_FLAG_CACHED = 0x80,
+ OID_FLAG_TYPE = 0x7f
+};
struct oid_t {
enum oid_num_t oid;
- short range; /* to define a range of oid */
- short size; /* max size of the associated data */
- char flags;
+ u16 range; /* to define a range of oid */
+ u16 size; /* max size of the associated data */
+ enum oid_types_t flags;
};
union oid_res_t {
@@ -496,8 +543,8 @@ union oid_res_t {
u32 u;
};
-#define IWMAX_BITRATES 20
-#define IWMAX_BSS 24
+#define IWMAX_BITRATES 20
+#define IWMAX_BSS 24
#define IWMAX_FREQ 30
#define PRIV_STR_SIZE 1024
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
index 1e0603c..e6d9b26 100644
--- a/drivers/net/wireless/prism54/islpci_dev.c
+++ b/drivers/net/wireless/prism54/islpci_dev.c
@@ -25,10 +25,10 @@
#include <linux/etherdevice.h>
#include <linux/delay.h>
#include <linux/if_arp.h>
+#include <linux/firmware.h>
#include <asm/io.h>
-#include "prismcompat.h"
#include "isl_38xx.h"
#include "isl_ioctl.h"
#include "islpci_dev.h"
@@ -86,7 +86,7 @@ isl_upload_firmware(islpci_private *priv
long fw_len;
const u32 *fw_ptr;
- rc = request_firmware(&fw_entry, priv->firmware, PRISM_FW_PDEV);
+ rc = request_firmware(&fw_entry, priv->firmware, &priv->pdev->dev);
if (rc) {
printk(KERN_ERR
"%s: request_firmware() failed for '%s'\n",
diff --git a/drivers/net/wireless/prism54/islpci_dev.h b/drivers/net/wireless/prism54/islpci_dev.h
index a9aa166..3d0bb8f 100644
--- a/drivers/net/wireless/prism54/islpci_dev.h
+++ b/drivers/net/wireless/prism54/islpci_dev.h
@@ -71,7 +71,6 @@ struct islpci_bss_wpa_ie {
u8 bssid[ETH_ALEN];
u8 wpa_ie[MAX_WPA_IE_LEN];
size_t wpa_ie_len;
-
};
typedef struct {
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
index 676d838..6da1f86 100644
--- a/drivers/net/wireless/prism54/islpci_eth.c
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -24,7 +24,6 @@
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
-#include "prismcompat.h"
#include "isl_38xx.h"
#include "islpci_eth.h"
#include "islpci_mgt.h"
@@ -482,8 +481,7 @@ islpci_eth_receive(islpci_private *priv)
void
islpci_do_reset_and_wake(void *data)
{
- islpci_private *priv = data;
-
+ islpci_private *priv = (islpci_private *) data;
islpci_reset(priv, 1);
priv->reset_task_pending = 0;
smp_wmb();
@@ -500,13 +498,12 @@ islpci_eth_tx_timeout(struct net_device
statistics->tx_errors++;
if (!priv->reset_task_pending) {
- printk(KERN_WARNING
- "%s: tx_timeout, scheduling reset", ndev->name);
+ printk(KERN_WARNING "%s: tx_timeout\n", ndev->name);
netif_stop_queue(ndev);
priv->reset_task_pending = 1;
schedule_work(&priv->reset_task);
} else {
printk(KERN_WARNING
- "%s: tx_timeout, waiting for reset", ndev->name);
+ "%s: tx_timeout, waiting for reset\n", ndev->name);
}
}
diff --git a/drivers/net/wireless/prism54/islpci_hotplug.c b/drivers/net/wireless/prism54/islpci_hotplug.c
index 58257b4..eba44e1 100644
--- a/drivers/net/wireless/prism54/islpci_hotplug.c
+++ b/drivers/net/wireless/prism54/islpci_hotplug.c
@@ -23,7 +23,6 @@
#include <linux/init.h> /* For __init, __exit */
#include <linux/dma-mapping.h>
-#include "prismcompat.h"
#include "islpci_dev.h"
#include "islpci_mgt.h" /* for pc_debug */
#include "isl_oid.h"
@@ -44,35 +43,15 @@ module_param(init_pcitm, int, 0);
* The latest list can be found at http://prism54.org/supported_cards.php */
static const struct pci_device_id prism54_id_tbl[] = {
/* Intersil PRISM Duette/Prism GT Wireless LAN adapter */
- {
- 0x1260, 0x3890,
- PCI_ANY_ID, PCI_ANY_ID,
- 0, 0, 0
- },
-
+ {PCI_DEVICE(0x1260, 0x3890)},
/* 3COM 3CRWE154G72 Wireless LAN adapter */
- {
- 0x10b7, 0x6001,
- PCI_ANY_ID, PCI_ANY_ID,
- 0, 0, 0
- },
-
+ {PCI_DEVICE(0x10b7, 0x6001)},
/* Intersil PRISM Indigo Wireless LAN adapter */
- {
- 0x1260, 0x3877,
- PCI_ANY_ID, PCI_ANY_ID,
- 0, 0, 0
- },
-
+ {PCI_DEVICE(0x1260, 0x3877)},
/* Intersil PRISM Javelin/Xbow Wireless LAN adapter */
- {
- 0x1260, 0x3886,
- PCI_ANY_ID, PCI_ANY_ID,
- 0, 0, 0
- },
-
+ {PCI_DEVICE(0x1260, 0x3886)},
/* End of list */
- {0,0,0,0,0,0,0}
+ { }
};
/* register the device with the Hotplug facilities of the kernel */
@@ -170,15 +149,15 @@ prism54_probe(struct pci_dev *pdev, cons
pci_set_master(pdev);
/* enable MWI */
- if (!pci_set_mwi(pdev))
- printk(KERN_INFO "%s: pci_set_mwi(pdev) succeeded\n", DRV_NAME);
+ if (pci_set_mwi(pdev))
+ printk(KERN_ERR "%s: pci_set_mwi failed\n", DRV_NAME);
/* setup the network device interface and its structure */
if (!(ndev = islpci_setup(pdev))) {
/* error configuring the driver as a network device */
printk(KERN_ERR "%s: could not configure network device\n",
DRV_NAME);
- goto do_pci_clear_mwi;
+ goto do_pci_release_regions;
}
priv = netdev_priv(ndev);
@@ -208,8 +187,6 @@ prism54_probe(struct pci_dev *pdev, cons
pci_set_drvdata(pdev, NULL);
free_netdev(ndev);
priv = NULL;
- do_pci_clear_mwi:
- pci_clear_mwi(pdev);
do_pci_release_regions:
pci_release_regions(pdev);
do_pci_disable_device:
@@ -257,8 +234,6 @@ prism54_remove(struct pci_dev *pdev)
free_netdev(ndev);
priv = NULL;
- pci_clear_mwi(pdev);
-
pci_release_regions(pdev);
pci_disable_device(pdev);
@@ -292,19 +267,15 @@ prism54_resume(struct pci_dev *pdev)
{
struct net_device *ndev = pci_get_drvdata(pdev);
islpci_private *priv = ndev ? netdev_priv(ndev) : NULL;
- int err;
-
BUG_ON(!priv);
- printk(KERN_NOTICE "%s: got resume request\n", ndev->name);
-
- err = pci_enable_device(pdev);
- if (err) {
- printk(KERN_ERR "%s: pci_enable_device failed on resume\n",
- ndev->name);
- return err;
+ if (pci_enable_device(pdev)) {
+ printk(KERN_ERR "%s: pci_enable_device() failed.\n", DRV_NAME);
+ return -ENODEV;
}
+ printk(KERN_NOTICE "%s: got resume request\n", ndev->name);
+
pci_restore_state(pdev);
/* alright let's go into the PREBOOT state */
diff --git a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c
index 036a875..8fd781d 100644
--- a/drivers/net/wireless/prism54/islpci_mgt.c
+++ b/drivers/net/wireless/prism54/islpci_mgt.c
@@ -25,7 +25,6 @@
#include <asm/system.h>
#include <linux/if_arp.h>
-#include "prismcompat.h"
#include "isl_38xx.h"
#include "islpci_mgt.h"
#include "isl_oid.h" /* additional types and defs for isl38xx fw */
diff --git a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c
index fbc52b6..24b5a49 100644
--- a/drivers/net/wireless/prism54/oid_mgt.c
+++ b/drivers/net/wireless/prism54/oid_mgt.c
@@ -16,7 +16,6 @@
*
*/
-#include "prismcompat.h"
#include "islpci_dev.h"
#include "islpci_mgt.h"
#include "isl_oid.h"
@@ -85,9 +84,9 @@ struct oid_t isl_oid[] = {
OID_U32_C(DOT11_OID_DEFKEYID, 0x12000003),
[DOT11_OID_DEFKEYX] = {0x12000004, 3, sizeof (struct obj_key),
OID_FLAG_CACHED | OID_TYPE_KEY}, /* DOT11_OID_DEFKEY1,...DOT11_OID_DEFKEY4 */
- OID_UNKNOWN(DOT11_OID_STAKEY, 0x12000008),
+ OID_STRUCT(DOT11_OID_STAKEY, 0x12000008, struct obj_stakey, OID_TYPE_STAKEY),
OID_U32(DOT11_OID_REKEYTHRESHOLD, 0x12000009),
- OID_UNKNOWN(DOT11_OID_STASC, 0x1200000a),
+ OID_STRUCT(DOT11_OID_STASC, 0x1200000a, struct obj_stasc, OID_TYPE_STASC),
OID_U32(DOT11_OID_PRIVTXREJECTED, 0x1a000000),
OID_U32(DOT11_OID_PRIVRXPLAIN, 0x1a000001),
@@ -122,9 +121,10 @@ struct oid_t isl_oid[] = {
OID_U32(DOT11_OID_BRIDGELOCAL, 0x15000000),
OID_U32(DOT11_OID_CLIENTS, 0x15000001),
OID_U32(DOT11_OID_CLIENTSASSOCIATED, 0x15000002),
- [DOT11_OID_CLIENTX] = {0x15000003, 2006, 0, 0}, /* DOT11_OID_CLIENTX,...DOT11_OID_CLIENT2007 */
+ [DOT11_OID_CLIENTX] = {0x15000003, 2006, sizeof(struct obj_sta),
+ OID_TYPE_STAINFO}, /* DOT11_OID_CLIENTX,...DOT11_OID_CLIENT2007 */
- OID_STRUCT(DOT11_OID_CLIENTFIND, 0x150007DB, u8[6], OID_TYPE_ADDR),
+ OID_STRUCT(DOT11_OID_CLIENTFIND, 0x150007DB, struct obj_sta, OID_TYPE_STAINFO),
OID_STRUCT(DOT11_OID_WDSLINKADD, 0x150007DC, u8[6], OID_TYPE_ADDR),
OID_STRUCT(DOT11_OID_WDSLINKREMOVE, 0x150007DD, u8[6], OID_TYPE_ADDR),
OID_STRUCT(DOT11_OID_EAPAUTHSTA, 0x150007DE, u8[6], OID_TYPE_ADDR),
@@ -201,8 +201,7 @@ struct oid_t isl_oid[] = {
OID_U32(DOT11_OID_STATIMEOUT, 0x19000000),
OID_U32_C(DOT11_OID_MLMEAUTOLEVEL, 0x19000001),
OID_U32(DOT11_OID_BSSTIMEOUT, 0x19000002),
- [DOT11_OID_ATTACHMENT] = {0x19000003, 0,
- sizeof(struct obj_attachment), OID_TYPE_ATTACH},
+ OID_STRUCT_C(DOT11_OID_ATTACHMENT, 0x19000003, sizeof(struct obj_attachment), OID_TYPE_ATTACH),
OID_STRUCT_C(DOT11_OID_PSMBUFFER, 0x19000004, struct obj_buffer,
OID_TYPE_BUFFER),
@@ -277,7 +276,7 @@ mgt_clean(islpci_private *priv)
}
void
-mgt_le_to_cpu(int type, void *data)
+mgt_le_to_cpu(enum oid_types_t type, void *data)
{
switch (type) {
case OID_TYPE_U32:
@@ -334,19 +333,31 @@ mgt_le_to_cpu(int type, void *data)
attach->id = le16_to_cpu(attach->id);
attach->size = le16_to_cpu(attach->size);
break;
- }
+ }
+ case OID_TYPE_STAKEY: {
+ struct obj_stakey *stakey = data;
+ stakey->options = le16_to_cpu(stakey->options);
+ break;
+ }
+ case OID_TYPE_STAINFO: {
+ struct obj_sta *sta = data;
+ sta->age = le16_to_cpu(sta->age);
+ break;
+ }
case OID_TYPE_SSID:
case OID_TYPE_KEY:
case OID_TYPE_ADDR:
case OID_TYPE_RAW:
+ case OID_TYPE_STASC:
break;
default:
BUG();
+ break;
}
}
static void
-mgt_cpu_to_le(int type, void *data)
+mgt_cpu_to_le(enum oid_types_t type, void *data)
{
switch (type) {
case OID_TYPE_U32:
@@ -403,14 +414,26 @@ mgt_cpu_to_le(int type, void *data)
attach->id = cpu_to_le16(attach->id);
attach->size = cpu_to_le16(attach->size);
break;
- }
+ }
+ case OID_TYPE_STAKEY: {
+ struct obj_stakey *stakey = data;
+ stakey->options = cpu_to_le16(stakey->options);
+ break;
+ }
+ case OID_TYPE_STAINFO: {
+ struct obj_sta *sta = data;
+ sta->age = cpu_to_le16(sta->age);
+ break;
+ }
case OID_TYPE_SSID:
case OID_TYPE_KEY:
case OID_TYPE_ADDR:
case OID_TYPE_RAW:
+ case OID_TYPE_STASC:
break;
default:
BUG();
+ break;
}
}
@@ -658,13 +681,16 @@ static enum oid_num_t commit_part1[] = {
static enum oid_num_t commit_part2[] = {
DOT11_OID_SSID,
+ /* problematic with WPA
DOT11_OID_PSMBUFFER,
+ */
DOT11_OID_AUTHENABLE,
DOT11_OID_PRIVACYINVOKED,
DOT11_OID_EXUNENCRYPTED,
DOT11_OID_DEFKEYX, /* MULTIPLE */
DOT11_OID_DEFKEYID,
DOT11_OID_DOT1XENABLE,
+ DOT11_OID_ATTACHMENT,
OID_INL_DOT11D_CONFORMANCE,
/* Do not initialize this - fw < 1.0.4.3 rejects it
OID_INL_OUTPUTPOWER,
diff --git a/drivers/net/wireless/prism54/oid_mgt.h b/drivers/net/wireless/prism54/oid_mgt.h
index 92c8a2d..10a5cc3 100644
--- a/drivers/net/wireless/prism54/oid_mgt.h
+++ b/drivers/net/wireless/prism54/oid_mgt.h
@@ -32,7 +32,7 @@ void mgt_clean(islpci_private *);
extern const int frequency_list_a[];
int channel_of_freq(int);
-void mgt_le_to_cpu(int, void *);
+void mgt_le_to_cpu(enum oid_types_t, void *);
int mgt_set_request(islpci_private *, enum oid_num_t, int, void *);
int mgt_set_varlen(islpci_private *, enum oid_num_t, void *, int);
diff --git a/drivers/net/wireless/prism54/prismcompat.h b/drivers/net/wireless/prism54/prismcompat.h
deleted file mode 100644
index aa1d174..0000000
--- a/drivers/net/wireless/prism54/prismcompat.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * (C) 2004 Margit Schubert-While <margitsw@t-online.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/*
- * Compatibility header file to aid support of different kernel versions
- */
-
-#ifdef PRISM54_COMPAT24
-#include "prismcompat24.h"
-#else /* PRISM54_COMPAT24 */
-
-#ifndef _PRISM_COMPAT_H
-#define _PRISM_COMPAT_H
-
-#include <linux/device.h>
-#include <linux/firmware.h>
-#include <linux/moduleparam.h>
-#include <linux/workqueue.h>
-#include <linux/compiler.h>
-
-#ifndef __iomem
-#define __iomem
-#endif
-
-#define PRISM_FW_PDEV &priv->pdev->dev
-
-#endif /* _PRISM_COMPAT_H */
-#endif /* PRISM54_COMPAT24 */
^ permalink raw reply related [flat|nested] 39+ messages in thread
* Re: [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
2006-11-25 16:50 ` chunkeey
@ 2006-11-26 5:27 ` Dmitry Torokhov
2006-11-26 10:47 ` chunkeey
0 siblings, 1 reply; 39+ messages in thread
From: Dmitry Torokhov @ 2006-11-26 5:27 UTC (permalink / raw)
To: chunkeey; +Cc: netdev, linville, Dan Williams
On Saturday 25 November 2006 11:50, chunkeey@web.de wrote:
> On Saturday, 25. November 2006 06:39, you wrote:
> > Ok, it looks like the patch changed the order of netdevice registration vs.
> > requesting firmware. My scripts are trying to set ESSID and keys before
> > firmware even gets loaded into the card. You may want to make sure that
> > newer distributions immune to such change before pushing the patch to
> > mainline.
>
> Ok, I think I know what was "wrong", this new patch should fix the problem.
> Can you try it?
>
Sorry, still need the second "ifup" to bring the card up after plugging
it in. ping -f looks good however, I will try to stress it more and will
report if I see anything wrong.
--
Dmitry
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
2006-11-26 5:27 ` Dmitry Torokhov
@ 2006-11-26 10:47 ` chunkeey
2006-12-06 1:44 ` John W. Linville
0 siblings, 1 reply; 39+ messages in thread
From: chunkeey @ 2006-11-26 10:47 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: netdev, Dmitry Torokhov, mcgrof
[-- Attachment #1: Type: text/plain, Size: 385 bytes --]
On Sunday, 26. November 2006 06:27, you wrote:
>
> Sorry, still need the second "ifup" to bring the card up after plugging
> it in. ping -f looks good however, I will try to stress it more and will
> report if I see anything wrong.
Well, some docs about the chips and firmware would be very handy...
has anyone access to conexant's library?
anyway, I spotted another little diff:
[-- Attachment #2: prism54-wpa-wl2.6-git-BOTH.diff --]
[-- Type: text/x-diff, Size: 81523 bytes --]
diff --git a/drivers/net/wireless/prism54/isl_38xx.c b/drivers/net/wireless/prism54/isl_38xx.c
index 02fc67b..044a23f 100644
--- a/drivers/net/wireless/prism54/isl_38xx.c
+++ b/drivers/net/wireless/prism54/isl_38xx.c
@@ -24,7 +24,6 @@
#include <asm/uaccess.h>
#include <asm/io.h>
-#include "prismcompat.h"
#include "isl_38xx.h"
#include "islpci_dev.h"
#include "islpci_mgt.h"
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 4a20e45..a9bc353 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -3,6 +3,7 @@
* (C) 2003,2004 Aurelien Alleaume <slts@free.fr>
* (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
* (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
+ * (C) 2006 Christian Lamparter <chunkeey@web.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,18 +27,13 @@
#include <asm/uaccess.h>
-#include "prismcompat.h"
#include "isl_ioctl.h"
#include "islpci_mgt.h"
#include "isl_oid.h" /* additional types and defs for isl38xx fw */
#include "oid_mgt.h"
#include <net/iw_handler.h> /* New driver API */
-
-#define KEY_SIZE_WEP104 13 /* 104/128-bit WEP keys */
-#define KEY_SIZE_WEP40 5 /* 40/64-bit WEP keys */
-/* KEY_SIZE_TKIP should match isl_oid.h, struct obj_key.key[] size */
-#define KEY_SIZE_TKIP 32 /* TKIP keys */
+#include <net/ieee80211.h>
static void prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid,
u8 *wpa_ie, size_t wpa_ie_len);
@@ -45,11 +41,6 @@ static size_t prism54_wpa_bss_ie_get(isl
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
@@ -167,14 +158,16 @@ prism54_update_stats(islpci_private *pri
if (down_interruptible(&priv->stats_sem))
return;
-/* Noise floor.
- * I'm not sure if the unit is dBm.
- * Note : If we are not connected, this value seems to be irrelevant. */
+ /* Noise floor.
+ * I'm not sure if the unit is dBm.
+
+ * Note :
+ * If we are not connected, this value seems to be irrelevant. */
mgt_get_request(priv, DOT11_OID_NOISEFLOOR, 0, NULL, &r);
priv->local_iwstatistics.qual.noise = r.u;
-/* Get the rssi of the link. To do this we need to retrieve a bss. */
+ /* Get the rssi of the link. To do this we need to retrieve a bss. */
/* First get the MAC address of the AP we are associated with. */
mgt_get_request(priv, DOT11_OID_BSSID, 0, NULL, &r);
@@ -199,11 +192,11 @@ prism54_update_stats(islpci_private *pri
/* report that the stats are new */
priv->local_iwstatistics.qual.updated = 0x7;
-/* Rx : unable to decrypt the MPDU */
+ /* Rx : unable to decrypt the MPDU */
mgt_get_request(priv, DOT11_OID_PRIVRXFAILED, 0, NULL, &r);
priv->local_iwstatistics.discard.code = r.u;
-/* Tx : Max MAC retries num reached */
+ /* Tx : Max MAC retries num reached */
mgt_get_request(priv, DOT11_OID_MPDUTXFAILED, 0, NULL, &r);
priv->local_iwstatistics.discard.retries = r.u;
@@ -227,7 +220,7 @@ prism54_get_wireless_stats(struct net_de
} else
priv->iwstatistics.qual.updated = 0;
- /* Update our wireless stats, but do not schedule to often
+ /* Update our wireless stats, but do not schedule too often
* (max 1 HZ) */
if ((priv->stats_timestamp == 0) ||
time_after(jiffies, priv->stats_timestamp + 1 * HZ)) {
@@ -414,6 +407,8 @@ prism54_get_sens(struct net_device *ndev
return rvalue;
}
+#define WEP40_KEY_LEN 5 /* 40/64-bit WEP keys */
+
static int
prism54_get_range(struct net_device *ndev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
@@ -435,11 +430,11 @@ prism54_get_range(struct net_device *nde
/* Now the encoding capabilities */
range->num_encoding_sizes = 3;
/* 64(40) bits WEP */
- range->encoding_size[0] = 5;
+ range->encoding_size[0] = WEP40_KEY_LEN;
/* 128(104) bits WEP */
- range->encoding_size[1] = 13;
+ range->encoding_size[1] = WEP_KEY_LEN;
/* 256 bits for WPA-PSK */
- range->encoding_size[2] = 32;
+ range->encoding_size[2] = SCM_KEY_LEN;
/* 4 keys are allowed */
range->max_encoding_tokens = 4;
@@ -565,6 +560,11 @@ prism54_set_scan(struct net_device *dev,
return 0;
}
+/* In 500 kbps */
+static const unsigned char scan_rate_list[] = { 2, 4, 11, 22,
+ 12, 18, 24, 36,
+ 48, 72, 96, 108 };
+
/* a little helper that will translate our data into a card independent
* format that the Wireless Tools will understand. This was inspired by
* the "Aironet driver for 4500 and 4800 series cards" (GPL)
@@ -596,17 +596,12 @@ prism54_translate_bss(struct net_device
current_ev = iwe_stream_add_point(current_ev, end_buf,
&iwe, bss->ssid.octets);
- /* Capabilities */
-#define CAP_ESS 0x01
-#define CAP_IBSS 0x02
-#define CAP_CRYPT 0x10
-
/* Mode */
cap = bss->capinfo;
iwe.u.mode = 0;
- if (cap & CAP_ESS)
+ if (cap & WLAN_CAPABILITY_ESS)
iwe.u.mode = IW_MODE_MASTER;
- else if (cap & CAP_IBSS)
+ else if (cap & WLAN_CAPABILITY_IBSS)
iwe.u.mode = IW_MODE_ADHOC;
iwe.cmd = SIOCGIWMODE;
if (iwe.u.mode)
@@ -615,7 +610,7 @@ prism54_translate_bss(struct net_device
IW_EV_UINT_LEN);
/* Encryption capability */
- if (cap & CAP_CRYPT)
+ if (cap & WLAN_CAPABILITY_PRIVACY)
iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
@@ -875,15 +870,6 @@ prism54_set_rate(struct net_device *ndev
data[1] = 0;
}
-/*
- i = 0;
- printk("prism54 rate: ");
- while(data[i]) {
- printk("%u ", data[i]);
- i++;
- }
- printk("0\n");
-*/
profile = -1;
ret = mgt_set_request(priv, DOT11_OID_PROFILES, 0, &profile);
ret |= mgt_set_request(priv, DOT11_OID_EXTENDEDRATES, 0, data);
@@ -1052,12 +1038,49 @@ prism54_get_retry(struct net_device *nde
}
static int
+prism54_set_auth_alg(islpci_private *priv, u32 flag)
+{
+ int authen = DOT11_AUTH_NONE, invoke = 0, exunencrypt = 0;
+ int ret;
+
+ if (flag & IW_ENCODE_RESTRICTED) {
+ authen = DOT11_AUTH_BOTH;
+ invoke = 1;
+ exunencrypt = 1;
+ }
+
+ if (flag & IW_ENCODE_OPEN) {
+ authen = DOT11_AUTH_OS;
+ invoke = 1;
+ /*
+ This is very wrong here, but we've to ensure bug-to-bug compatibility.
+
+ If we set exunencrypt, the Firmware adds the "Privacy" flag to the
+ Capability Information, which is misreaded by many STA/AP as
+ "the device supports WEP, WPA and WPA2"
+ */
+ exunencrypt = 1;
+ }
+
+ ret =
+ mgt_set_request(priv, DOT11_OID_AUTHENABLE,
+ 0, &authen);
+ ret |=
+ mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED,
+ 0, &invoke);
+ ret |=
+ mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED,
+ 0,&exunencrypt);
+
+ return ret;
+}
+
+static int
prism54_set_encode(struct net_device *ndev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
- int rvalue = 0, force = 0;
- int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0;
+ int rvalue = 0, flags = dwrq->flags;
union oid_res_t r;
/* with the new API, it's impossible to get a NULL pointer.
@@ -1071,27 +1094,27 @@ prism54_set_encode(struct net_device *nd
struct obj_key key = { DOT11_PRIV_WEP, 0, "" };
/* get the current key index */
- rvalue = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
+ rvalue |= mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
current_index = r.u;
/* Verify that the key is not marked as invalid */
if (!(dwrq->flags & IW_ENCODE_NOKEY)) {
- if (dwrq->length > KEY_SIZE_TKIP) {
+ if (dwrq->length > MAX_KEY_LEN) {
/* User-provided key data too big */
return -EINVAL;
}
- if (dwrq->length > KEY_SIZE_WEP104) {
+ if (dwrq->length > WEP_KEY_LEN) {
/* WPA-PSK TKIP */
key.type = DOT11_PRIV_TKIP;
- key.length = KEY_SIZE_TKIP;
- } else if (dwrq->length > KEY_SIZE_WEP40) {
+ key.length = MAX_KEY_LEN;
+ } else if (dwrq->length > WEP40_KEY_LEN) {
/* WEP 104/128 */
- key.length = KEY_SIZE_WEP104;
+ key.length = WEP_KEY_LEN;
} else {
/* WEP 40/64 */
- key.length = KEY_SIZE_WEP40;
+ key.length = WEP40_KEY_LEN;
}
memset(key.key, 0, sizeof (key.key));
- memcpy(key.key, extra, dwrq->length);
+ memcpy(key.key, extra, key.length);
if ((index < 0) || (index > 3))
/* no index provided use the current one */
@@ -1108,95 +1131,111 @@ prism54_set_encode(struct net_device *nd
* This is also how "iwconfig ethX key on" works
*/
if ((index == current_index) && (key.length > 0))
- force = 1;
+ flags |= IW_ENCODE_RESTRICTED;
} else {
- int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
+ int index = (flags & IW_ENCODE_INDEX) - 1;
if ((index >= 0) && (index <= 3)) {
/* we want to set the key index */
rvalue |=
mgt_set_request(priv, DOT11_OID_DEFKEYID, 0,
&index);
} else {
- if (!dwrq->flags & IW_ENCODE_MODE) {
+ if (!(flags & IW_ENCODE_MODE)) {
/* we cannot do anything. Complain. */
return -EINVAL;
}
}
}
- /* now read the flags */
- if (dwrq->flags & IW_ENCODE_DISABLED) {
- /* Encoding disabled,
- * authen = DOT11_AUTH_OS;
- * invoke = 0;
- * exunencrypt = 0; */
- }
- if (dwrq->flags & IW_ENCODE_OPEN)
- /* Encode but accept non-encoded packets. No auth */
- invoke = 1;
- if ((dwrq->flags & IW_ENCODE_RESTRICTED) || force) {
- /* Refuse non-encoded packets. Auth */
- authen = DOT11_AUTH_BOTH;
- invoke = 1;
- exunencrypt = 1;
- }
/* do the change if requested */
- if ((dwrq->flags & IW_ENCODE_MODE) || force) {
- rvalue |=
- mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
- rvalue |=
- mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &invoke);
- rvalue |=
- mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0,
- &exunencrypt);
- }
+ if (flags & IW_ENCODE_MODE)
+ rvalue = prism54_set_auth_alg(priv, flags);
+
return rvalue;
}
static int
+prism54_get_auth_algs(islpci_private *priv)
+{
+ u32 authen = 0, invoke = 0, exunencrypt = 0;
+ union oid_res_t r;
+ int ret = 0;
+
+ ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
+ authen = r.u;
+ ret |= mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
+ invoke = r.u;
+ ret |= mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
+ exunencrypt = r.u;
+
+ if (ret)
+ return ret;
+
+ if (invoke && exunencrypt &&
+ ((authen == DOT11_AUTH_SK) || (authen == DOT11_AUTH_BOTH)))
+ ret = IW_ENCODE_RESTRICTED | IW_ENCODE_ENABLED;
+ else if ((authen == DOT11_AUTH_OS)) {
+ if (invoke)
+ ret = IW_ENCODE_OPEN | IW_ENCODE_ENABLED;
+ else {
+ ret = IW_ENCODE_DISABLED;
+ }
+ }
+ else {
+ ret = IW_ENCODE_DISABLED;
+ }
+
+ return ret;
+}
+
+static int
prism54_get_encode(struct net_device *ndev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
struct obj_key *key;
u32 devindex, index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
- u32 authen = 0, invoke = 0, exunencrypt = 0;
- int rvalue;
+ int rvalue = 0, flags;
union oid_res_t r;
+ if (islpci_get_state(priv) < PRV_STATE_INIT) {
+ dwrq->flags = IW_ENCODE_DISABLED;
+ dwrq->length = 0;
+ return 0;
+ }
+
/* first get the flags */
- rvalue = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
- authen = r.u;
- rvalue |= mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
- invoke = r.u;
- rvalue |= mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
- exunencrypt = r.u;
+ if ((flags = prism54_get_auth_algs(priv)) < 0)
+ return rvalue;
- if (invoke && (authen == DOT11_AUTH_BOTH) && exunencrypt)
- dwrq->flags = IW_ENCODE_RESTRICTED;
- else if ((authen == DOT11_AUTH_OS) && !exunencrypt) {
- if (invoke)
- dwrq->flags = IW_ENCODE_OPEN;
- else
- dwrq->flags = IW_ENCODE_DISABLED;
- } else
- /* The card should not work in this state */
- dwrq->flags = 0;
+ memset(extra, 0x0, dwrq->length);
+ dwrq->flags = flags;
- /* get the current device key index */
- 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))
- /* no index provided, use the current one */
- index = devindex;
- rvalue |= mgt_get_request(priv, DOT11_OID_DEFKEYX, index, NULL, &r);
- key = r.ptr;
- dwrq->length = key->length;
- memcpy(extra, key->key, dwrq->length);
- kfree(key);
- /* return the used key index */
- dwrq->flags |= devindex + 1;
+ if (flags != IW_ENCODE_DISABLED) {
+ /* get the current device key index */
+ 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))
+ /* no index provided, use the current one */
+ index = devindex;
+ rvalue |= mgt_get_request(priv, DOT11_OID_DEFKEYX, index, NULL, &r);
+ key = r.ptr;
+
+ if (dwrq->length < key->length) {
+ kfree(key);
+ return -EINVAL;
+ }
+
+ dwrq->length = key->length;
+ memcpy(extra, key->key, dwrq->length);
+ kfree(key);
+ /* return the used key index */
+ dwrq->flags |= devindex + 1;
+ } else
+ rvalue = 0;
+
return rvalue;
}
@@ -1212,7 +1251,7 @@ prism54_get_txpower(struct net_device *n
/* intersil firmware operates in 0.25 dBm (1/4 dBm) */
vwrq->value = (s32) r.u / 4;
vwrq->fixed = 1;
- /* radio is not turned of
+ /* radio is not turned off
* btw: how is possible to turn off only the radio
*/
vwrq->disabled = 0;
@@ -1246,58 +1285,72 @@ prism54_set_txpower(struct net_device *n
}
}
-static int prism54_set_genie(struct net_device *ndev,
- struct iw_request_info *info,
- struct iw_point *data, char *extra)
+static int
+prism54_set_attachment(islpci_private *priv, u8 frame_type,
+ int length, u8* attachment)
{
- islpci_private *priv = netdev_priv(ndev);
- int alen, ret = 0;
+ struct obj_attachment null_attach;
struct obj_attachment *attach;
+ int ret;
+
+ attach = kzalloc(sizeof(*attach) + length, GFP_KERNEL);
+ if (!attach)
+ return -ENOMEM;
+
+ memset(&null_attach, 0, sizeof(null_attach));
+
+ /* Note: endianness is covered by mgt_set_varlen */
+ null_attach.id = attach->id = -1; // use the global ID
+ attach->size = length;
+ attach->type = frame_type;
+ memcpy(attach->data, attachment, length);
+
+ /* clear the last element, before set the new one */
+ ret = mgt_set_request(priv, DOT11_OID_ATTACHMENT, 0 ,&null_attach);
+ ret |= mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach, length);
+
+ kfree(attach);
+
+ return ret;
+}
+
+static int
+prism54_set_genie(struct net_device *ndev, struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ islpci_private *priv = netdev_priv(ndev);
+ int ret = 0;
if (data->length > MAX_WPA_IE_LEN ||
(data->length && extra == NULL))
return -EINVAL;
+ if (islpci_get_state(priv) < PRV_STATE_INIT)
+ return -EINVAL;
+
memcpy(priv->wpa_ie, extra, data->length);
priv->wpa_ie_len = data->length;
- alen = sizeof(*attach) + priv->wpa_ie_len;
- attach = kzalloc(alen, GFP_KERNEL);
- if (attach == NULL)
- return -ENOMEM;
-
-#define WLAN_FC_TYPE_MGMT 0
-#define WLAN_FC_STYPE_ASSOC_REQ 0
-#define WLAN_FC_STYPE_REASSOC_REQ 2
-
- /* Note: endianness is covered by mgt_set_varlen */
- attach->type = (WLAN_FC_TYPE_MGMT << 2) |
- (WLAN_FC_STYPE_ASSOC_REQ << 4);
- attach->id = -1;
- attach->size = priv->wpa_ie_len;
- memcpy(attach->data, extra, priv->wpa_ie_len);
-
- ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach,
- priv->wpa_ie_len);
- if (ret == 0) {
- attach->type = (WLAN_FC_TYPE_MGMT << 2) |
- (WLAN_FC_STYPE_REASSOC_REQ << 4);
-
- ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach,
- priv->wpa_ie_len);
- if (ret == 0)
- printk(KERN_DEBUG "%s: WPA IE Attachment was set\n",
- ndev->name);
+ if (priv->iw_mode == IW_MODE_MASTER) {
+ ret = prism54_set_attachment(priv, IEEE80211_STYPE_PROBE_RESP,
+ data->length, extra);
+ ret |= prism54_set_attachment(priv, IEEE80211_STYPE_BEACON,
+ data->length, extra);
+ }
+ else {
+ ret = prism54_set_attachment(priv, IEEE80211_STYPE_REASSOC_REQ,
+ data->length, extra);
+ ret |= prism54_set_attachment(priv, IEEE80211_STYPE_ASSOC_REQ,
+ data->length, extra);
}
- kfree(attach);
return ret;
}
-static int prism54_get_genie(struct net_device *ndev,
- struct iw_request_info *info,
- struct iw_point *data, char *extra)
+static int
+prism54_get_genie(struct net_device *ndev, struct iw_request_info *info,
+ struct iw_point *data, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
int len = priv->wpa_ie_len;
@@ -1316,38 +1369,14 @@ static int prism54_get_genie(struct net_
return 0;
}
-static int prism54_set_auth(struct net_device *ndev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
+static int
+prism54_set_auth(struct net_device *ndev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
struct iw_param *param = &wrqu->param;
- u32 mlmelevel = 0, authen = 0, dot1x = 0;
- u32 exunencrypt = 0, privinvoked = 0, wpa = 0;
- u32 old_wpa;
- int ret = 0;
- union oid_res_t r;
-
- if (islpci_get_state(priv) < PRV_STATE_INIT)
- return 0;
-
- /* first get the flags */
- down_write(&priv->mib_sem);
- wpa = old_wpa = priv->wpa;
- up_write(&priv->mib_sem);
- ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
- authen = r.u;
- ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
- privinvoked = r.u;
- ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
- exunencrypt = r.u;
- ret = mgt_get_request(priv, DOT11_OID_DOT1XENABLE, 0, NULL, &r);
- dot1x = r.u;
- ret = mgt_get_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, NULL, &r);
- mlmelevel = r.u;
-
- if (ret < 0)
- goto out;
+ u32 set = 0;
+ int rvalue = 0;
switch (param->flags & IW_AUTH_INDEX) {
case IW_AUTH_CIPHER_PAIRWISE:
@@ -1355,103 +1384,72 @@ static int prism54_set_auth(struct net_d
case IW_AUTH_KEY_MGMT:
break;
- case IW_AUTH_WPA_ENABLED:
- /* Do the same thing as IW_AUTH_WPA_VERSION */
- if (param->value) {
- wpa = 1;
- privinvoked = 1; /* For privacy invoked */
- exunencrypt = 1; /* Filter out all unencrypted frames */
- dot1x = 0x01; /* To enable eap filter */
- mlmelevel = DOT11_MLME_EXTENDED;
- authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
- } else {
- wpa = 0;
- privinvoked = 0;
- exunencrypt = 0; /* Do not filter un-encrypted data */
- dot1x = 0;
- mlmelevel = DOT11_MLME_AUTO;
- }
- break;
-
case IW_AUTH_WPA_VERSION:
- if (param->value & IW_AUTH_WPA_VERSION_DISABLED) {
- wpa = 0;
- privinvoked = 0;
- exunencrypt = 0; /* Do not filter un-encrypted data */
- dot1x = 0;
- mlmelevel = DOT11_MLME_AUTO;
- } else {
- if (param->value & IW_AUTH_WPA_VERSION_WPA)
- wpa = 1;
- else if (param->value & IW_AUTH_WPA_VERSION_WPA2)
- wpa = 2;
- privinvoked = 1; /* For privacy invoked */
- exunencrypt = 1; /* Filter out all unencrypted frames */
- dot1x = 0x01; /* To enable eap filter */
- mlmelevel = DOT11_MLME_EXTENDED;
- authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
- }
+ if (set & IW_AUTH_WPA_VERSION_WPA)
+ set = 1;
+ if (set & IW_AUTH_WPA_VERSION_WPA2)
+ set |= 2;
+ case IW_AUTH_WPA_ENABLED:
+ if (!set)
+ set = param->value ? 3 : 0;
+ rvalue = prism54_set_wpa(ndev, info, &set, extra);
break;
case IW_AUTH_RX_UNENCRYPTED_EAPOL:
- dot1x = param->value ? 1 : 0;
+ set = param->value ? 1 : 0;
+ rvalue = mgt_set_request(priv, DOT11_OID_DOT1XENABLE,
+ 0, &set);
break;
case IW_AUTH_PRIVACY_INVOKED:
- privinvoked = param->value ? 1 : 0;
+ set = param->value ? 1 : 0;
+ rvalue = mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED,
+ 0, &set);
+ break;
case IW_AUTH_DROP_UNENCRYPTED:
- exunencrypt = param->value ? 1 : 0;
+ set = param->value ? 1 : 0;
+ rvalue = mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED,
+ 0, &set);
break;
case IW_AUTH_80211_AUTH_ALG:
- if (param->value & IW_AUTH_ALG_SHARED_KEY) {
- /* Only WEP uses _SK and _BOTH */
- if (wpa > 0) {
- ret = -EINVAL;
- goto out;
- }
- authen = DOT11_AUTH_SK;
- } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
- authen = DOT11_AUTH_OS;
- } else {
- ret = -EINVAL;
- goto out;
+ switch (param->value) {
+ case IW_AUTH_ALG_OPEN_SYSTEM:
+ set = DOT11_AUTH_OS;
+ break;
+ case IW_AUTH_ALG_SHARED_KEY:
+ set = DOT11_AUTH_SK;
+ break;
+ default:
+ return -EINVAL;
+ break;
}
+ rvalue = mgt_set_request(priv, DOT11_OID_AUTHENABLE,
+ 0, &set);
break;
default:
- return -EOPNOTSUPP;
+ rvalue = -EOPNOTSUPP;
+ break;
}
- /* Set all the values */
- down_write(&priv->mib_sem);
- priv->wpa = wpa;
- up_write(&priv->mib_sem);
- mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
- mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &privinvoked);
- mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0, &exunencrypt);
- mgt_set_request(priv, DOT11_OID_DOT1XENABLE, 0, &dot1x);
- mgt_set_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, &mlmelevel);
-
-out:
- return ret;
+ return rvalue;
}
-static int prism54_get_auth(struct net_device *ndev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
+static int
+prism54_get_auth(struct net_device *ndev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
struct iw_param *param = &wrqu->param;
- u32 wpa = 0;
- int ret = 0;
union oid_res_t r;
+ u32 wpa = 0;
+ int rvalue = 0;
if (islpci_get_state(priv) < PRV_STATE_INIT)
return 0;
- /* first get the flags */
down_write(&priv->mib_sem);
wpa = priv->wpa;
up_write(&priv->mib_sem);
@@ -1463,272 +1461,287 @@ static int prism54_get_auth(struct net_d
/*
* wpa_supplicant will control these internally
*/
- ret = -EOPNOTSUPP;
- break;
+ param->value = 0;
+ return -EOPNOTSUPP;
+ break;
case IW_AUTH_WPA_VERSION:
- switch (wpa) {
- case 1:
- param->value = IW_AUTH_WPA_VERSION_WPA;
- break;
- case 2:
- param->value = IW_AUTH_WPA_VERSION_WPA2;
- break;
- case 0:
- default:
+ if (!wpa)
param->value = IW_AUTH_WPA_VERSION_DISABLED;
- break;
- }
+ if (wpa & 1)
+ param->value = IW_AUTH_WPA_VERSION_WPA;
+ if (wpa & 2)
+ param->value |= IW_AUTH_WPA_VERSION_WPA2;
+
break;
case IW_AUTH_DROP_UNENCRYPTED:
- ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
- if (ret >= 0)
- param->value = r.u > 0 ? 1 : 0;
+ rvalue = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED,
+ 0, NULL, &r);
+ param->value = r.u;
break;
case IW_AUTH_80211_AUTH_ALG:
- ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
- if (ret >= 0) {
- switch (r.u) {
- case DOT11_AUTH_OS:
- param->value = IW_AUTH_ALG_OPEN_SYSTEM;
- break;
- case DOT11_AUTH_BOTH:
- case DOT11_AUTH_SK:
- param->value = IW_AUTH_ALG_SHARED_KEY;
- case DOT11_AUTH_NONE:
- default:
- param->value = 0;
- break;
- }
+ rvalue = mgt_get_request(priv, DOT11_OID_AUTHENABLE,
+ 0, NULL, &r);
+
+ switch (r.u) {
+ case DOT11_AUTH_OS:
+ param->value = IW_AUTH_ALG_OPEN_SYSTEM;
+ break;
+ case DOT11_AUTH_BOTH:
+ case DOT11_AUTH_SK:
+ param->value = IW_AUTH_ALG_SHARED_KEY;
+ break;
+ default:
+ param->value = 0;
+ rvalue = -EOPNOTSUPP;
+ break;
}
break;
case IW_AUTH_WPA_ENABLED:
- param->value = wpa > 0 ? 1 : 0;
+ param->value = wpa ? 0 : 1;
break;
case IW_AUTH_RX_UNENCRYPTED_EAPOL:
- ret = mgt_get_request(priv, DOT11_OID_DOT1XENABLE, 0, NULL, &r);
- if (ret >= 0)
- param->value = r.u > 0 ? 1 : 0;
+ rvalue = mgt_get_request(priv, DOT11_OID_DOT1XENABLE,
+ 0, NULL, &r);
+ param->value = r.u;
break;
case IW_AUTH_PRIVACY_INVOKED:
- ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
- if (ret >= 0)
- param->value = r.u > 0 ? 1 : 0;
+ rvalue = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED,
+ 0, NULL, &r);
+ param->value = r.u;
break;
default:
return -EOPNOTSUPP;
+ break;
}
- return ret;
+
+ return 0;
}
-static int prism54_set_encodeext(struct net_device *ndev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+static int
+prism54_set_encodeext(struct net_device *ndev, struct iw_request_info *info,
+ struct iw_point *dwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
- struct iw_point *encoding = &wrqu->encoding;
- struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- int idx, alg = ext->alg, set_key = 1;
+ struct iw_encode_ext *enc = (struct iw_encode_ext *)extra;
+ struct obj_stakey* key;
union oid_res_t r;
- int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0;
- int ret = 0;
-
- if (islpci_get_state(priv) < PRV_STATE_INIT)
- return 0;
-
- /* Determine and validate the key index */
- idx = (encoding->flags & IW_ENCODE_INDEX) - 1;
- if (idx) {
- if (idx < 0 || idx > 3)
- return -EINVAL;
- } else {
- ret = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
- if (ret < 0)
- goto out;
- idx = r.u;
- }
-
- if (encoding->flags & IW_ENCODE_DISABLED)
- alg = IW_ENCODE_ALG_NONE;
+ int index, key_type, keyop = DOT11_KEYOP_SET_KEY;
+ int ret = -EINVAL;
- if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
- /* Only set transmit key index here, actual
- * key is set below if needed.
- */
- ret = mgt_set_request(priv, DOT11_OID_DEFKEYID, 0, &idx);
- set_key = ext->key_len > 0 ? 1 : 0;
- }
+ if ((enc->key_len > (dwrq->length - sizeof(*enc))) ||
+ (enc->addr.sa_family != ARPHRD_ETHER))
+ return -EINVAL;
- if (set_key) {
- struct obj_key key = { DOT11_PRIV_WEP, 0, "" };
- switch (alg) {
+ switch (enc->alg) {
case IW_ENCODE_ALG_NONE:
+ key_type = DOT11_PRIV_WEP;
+ keyop = DOT11_KEYOP_REMOVE_KEY;
break;
case IW_ENCODE_ALG_WEP:
- if (ext->key_len > KEY_SIZE_WEP104) {
- ret = -EINVAL;
- goto out;
- }
- if (ext->key_len > KEY_SIZE_WEP40)
- key.length = KEY_SIZE_WEP104;
- else
- key.length = KEY_SIZE_WEP40;
+ key_type = DOT11_PRIV_WEP;
break;
case IW_ENCODE_ALG_TKIP:
- if (ext->key_len > KEY_SIZE_TKIP) {
- ret = -EINVAL;
- goto out;
- }
- key.type = DOT11_PRIV_TKIP;
- key.length = KEY_SIZE_TKIP;
+ key_type = DOT11_PRIV_TKIP;
+ break;
default:
- return -EINVAL;
- }
-
- if (key.length) {
- memset(key.key, 0, sizeof(key.key));
- memcpy(key.key, ext->key, ext->key_len);
- ret = mgt_set_request(priv, DOT11_OID_DEFKEYX, idx,
- &key);
- if (ret < 0)
- goto out;
- }
+ return -EOPNOTSUPP;
}
- /* Read the flags */
- if (encoding->flags & IW_ENCODE_DISABLED) {
- /* Encoding disabled,
- * authen = DOT11_AUTH_OS;
- * invoke = 0;
- * exunencrypt = 0; */
- }
- if (encoding->flags & IW_ENCODE_OPEN) {
- /* Encode but accept non-encoded packets. No auth */
- invoke = 1;
- }
- if (encoding->flags & IW_ENCODE_RESTRICTED) {
- /* Refuse non-encoded packets. Auth */
- authen = DOT11_AUTH_BOTH;
- invoke = 1;
- exunencrypt = 1;
+ index = (dwrq->flags & IW_ENCODE_INDEX);
+ if ((index < 0) || (index > 3)) {
+ /* no index provided, so get the current one */
+ ret = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
+ if (ret)
+ return ret;
+ index = r.u;
}
- /* do the change if requested */
- if (encoding->flags & IW_ENCODE_MODE) {
- ret = mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0,
- &authen);
- ret = mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0,
- &invoke);
- ret = mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0,
- &exunencrypt);
+ key = kzalloc(sizeof(*key) + enc->key_len, GFP_KERNEL);
+ if (!key)
+ return -ENOMEM;
+
+ key->type = key_type;
+ key->length = enc->key_len;
+ key->keyid = index;
+ key->reserved = keyop;
+ if (!(enc->ext_flags & IW_ENCODE_EXT_GROUP_KEY))
+ key->options = DOT11_STAKEY_OPTION_DEFAULTKEY;
+ else
+ key->options = DOT11_STAKEY_OPTION_GROUPKEY;
+
+ memcpy(key->key, enc->key, key->length);
+ memcpy(key->address, enc->addr.sa_data, ETH_ALEN);
+
+ ret = mgt_set_request(priv, DOT11_OID_STAKEY, 0, key);
+ kfree(key);
+ if (ret)
+ return ret;
+
+ if (enc->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
+ struct obj_stasc *stasc;
+ stasc = kzalloc(sizeof(*stasc), GFP_KERNEL);
+ if (!stasc)
+ return -ENOMEM;
+ memcpy(stasc->address, enc->addr.sa_data, ETH_ALEN);
+ stasc->keyid = index;
+ stasc->tx_sc = 1;
+ memcpy(stasc->sc, enc->rx_seq, 6);
+ ret = mgt_set_request(priv, DOT11_OID_STASC, 0, stasc);
+ kfree(stasc);
+ if (ret)
+ return ret;
}
-out:
+ if (dwrq->flags & IW_ENCODE_MODE)
+ ret = prism54_set_auth_alg(priv, dwrq->flags);
+
return ret;
}
-
-static int prism54_get_encodeext(struct net_device *ndev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+static int
+prism54_get_encodeext(struct net_device *ndev,
+ struct iw_request_info *info, struct iw_point *dwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
- struct iw_point *encoding = &wrqu->encoding;
- struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- int idx, max_key_len;
+ struct iw_encode_ext *enc = (struct iw_encode_ext *)extra;
+ struct obj_stasc *stasc;
union oid_res_t r;
- int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0, wpa = 0;
- int ret = 0;
+ int index;
+ int ret = -EINVAL;
+ int max_key_len;
- if (islpci_get_state(priv) < PRV_STATE_INIT)
- return 0;
-
- /* first get the flags */
- ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
- authen = r.u;
- ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
- invoke = r.u;
- ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
- exunencrypt = r.u;
- if (ret < 0)
- goto out;
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
- max_key_len = encoding->length - sizeof(*ext);
+ max_key_len = dwrq->length - sizeof(*enc);
if (max_key_len < 0)
return -EINVAL;
- idx = (encoding->flags & IW_ENCODE_INDEX) - 1;
- if (idx) {
- if (idx < 0 || idx > 3)
- return -EINVAL;
- } else {
+ memset(enc, 0, sizeof(*enc));
+
+ if (islpci_get_state(priv) < PRV_STATE_INIT) {
+ dwrq->flags = IW_ENCODE_DISABLED;
+ return 0;
+ }
+
+ index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
+ if ((index < 0) || (index > 3)) {
+ /* no index provided, so get the current one */
ret = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
- if (ret < 0)
- goto out;
- idx = r.u;
+ if (ret)
+ return ret;
+ index = r.u;
}
- encoding->flags = idx + 1;
- memset(ext, 0, sizeof(*ext));
+ if (enc->addr.sa_family != ARPHRD_ETHER) {
+ /* no "per-station key" */
+ struct obj_key *key;
+ ret = mgt_get_request(priv, DOT11_OID_DEFKEYX, index, NULL, &r);
+ key = r.ptr;
+ if (ret) {
+ kfree(key);
+ return ret;
+ }
- switch (authen) {
- case DOT11_AUTH_BOTH:
- case DOT11_AUTH_SK:
- wrqu->encoding.flags |= IW_ENCODE_RESTRICTED;
- case DOT11_AUTH_OS:
- default:
- wrqu->encoding.flags |= IW_ENCODE_OPEN;
+ if (key->length > max_key_len) {
+ kfree(key);
+ return -E2BIG;
+ }
+
+ enc->key_len = key->length;
+ switch (key->type) {
+ case DOT11_PRIV_WEP:
+ enc->alg = IW_ENCODE_ALG_WEP;
+ break;
+ case DOT11_PRIV_TKIP:
+ enc->alg = IW_ENCODE_ALG_TKIP;
break;
- }
+ default:
+ kfree(key);
+ return -EIO;
+ break;
+ }
- down_write(&priv->mib_sem);
- wpa = priv->wpa;
- up_write(&priv->mib_sem);
+ dwrq->flags |= IW_ENCODE_ENABLED;
+ memcpy(enc->key, key->key, enc->key_len);
+ dwrq->flags |= index +1;
+ return ret;
- if (authen == DOT11_AUTH_OS && !exunencrypt && !invoke && !wpa) {
- /* No encryption */
- ext->alg = IW_ENCODE_ALG_NONE;
- ext->key_len = 0;
- wrqu->encoding.flags |= IW_ENCODE_DISABLED;
- } else {
- struct obj_key *key;
+ }
+ else {
+ /* no "per-station key" */
+ struct obj_stakey *key;
+ key = kzalloc(sizeof(*key), GFP_KERNEL);
+ if (!key)
+ return -ENOMEM;
+
+ memcpy(key->address, enc->addr.sa_data, ETH_ALEN);
+ key->keyid = index;
+ ret = mgt_get_request(priv, DOT11_OID_STAKEY, 0, (void*)key, &r);
+ kfree(key);
+ key = (struct obj_stakey*)r.ptr;
+ if (ret) {
+ kfree(key);
+ return ret;
+ }
- ret = mgt_get_request(priv, DOT11_OID_DEFKEYX, idx, NULL, &r);
- if (ret < 0)
- goto out;
- key = r.ptr;
- if (max_key_len < key->length) {
- ret = -E2BIG;
- goto out;
+ if (key->length > max_key_len) {
+ kfree(key);
+ return -EINVAL;
}
- memcpy(ext->key, key->key, key->length);
- ext->key_len = key->length;
switch (key->type) {
- case DOT11_PRIV_TKIP:
- ext->alg = IW_ENCODE_ALG_TKIP;
+ case DOT11_PRIV_WEP:
+ enc->alg = IW_ENCODE_ALG_WEP;
break;
- default:
- case DOT11_PRIV_WEP:
- ext->alg = IW_ENCODE_ALG_WEP;
+ case DOT11_PRIV_TKIP:
+ enc->alg = IW_ENCODE_ALG_TKIP;
+ break;
+ default:
+ kfree(key);
+ return -EIO;
break;
}
- wrqu->encoding.flags |= IW_ENCODE_ENABLED;
+
+ enc->key_len = key->length;
+ dwrq->flags = index + 1;
+ memcpy(enc->key, key->key, key->length);
+ kfree(key);
+
+ /* add replay counter */
+ stasc = kzalloc(sizeof(*stasc), GFP_KERNEL);
+ if (!stasc)
+ return -ENOMEM;
+
+ memcpy(stasc->address, enc->addr.sa_data, ETH_ALEN);
+ stasc->keyid = index;
+ stasc->tx_sc = 1;
+ ret = mgt_get_request(priv, DOT11_OID_STASC, 0, (void*)stasc, &r);
+ kfree(stasc);
+ stasc = (struct obj_stasc*)r.ptr;
+ if (ret) {
+ kfree(stasc);
+ return ret;
+ }
+
+ memset(enc->tx_seq, 0, IW_ENCODE_SEQ_MAX_SIZE);
+ // prism's FW has only a 6 byte wide RSC!
+ memcpy(enc->tx_seq, stasc->sc, IW_ENCODE_SEQ_MAX_SIZE - 2);
+ enc->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID;
+ kfree(stasc);
+
}
-out:
return ret;
}
-
static int
prism54_reset(struct net_device *ndev, struct iw_request_info *info,
__u32 * uwrq, char *extra)
@@ -2030,14 +2043,12 @@ 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 " MAC_FMT " [%2.2x %2.2X %4.4X]",
str,
((priv->iw_mode == IW_MODE_MASTER) ? "from" : "to"),
- a[0], a[1], a[2], a[3], a[4], a[5],
- (error ? (mlme->code ? " : REJECTED " : " : ACCEPTED ")
- : ""), mlme->code);
+ MAC_ARG(mlme->address),
+ mlme->state, mlme->code, mlme->id);
BUG_ON(n > IW_CUSTOM_MAX);
*length = n;
}
@@ -2103,12 +2114,6 @@ struct ieee80211_beacon_phdr {
u16 capab_info;
} __attribute__ ((packed));
-#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)
@@ -2140,10 +2145,9 @@ prism54_wpa_bss_ie_add(islpci_private *p
struct islpci_bss_wpa_ie, list);
list_del(&bss->list);
} else {
- bss = kmalloc(sizeof (*bss), GFP_ATOMIC);
+ bss = kzalloc(sizeof(*bss), GFP_ATOMIC);
if (bss != NULL) {
priv->num_bss_wpa++;
- memset(bss, 0, sizeof (*bss));
}
}
if (bss != NULL) {
@@ -2157,8 +2161,8 @@ prism54_wpa_bss_ie_add(islpci_private *p
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 " MAC_FMT
+ "\n", MAC_ARG(bssid));
}
/* expire old entries from WPA list */
@@ -2220,6 +2224,8 @@ prism54_wpa_bss_ie_clean(islpci_private
}
}
+static u8 wpa_oid[4] = { 0x00, 0x50, 0xf2, 1 };
+
static void
prism54_process_bss_data(islpci_private *priv, u32 oid, u8 *addr,
u8 *payload, size_t len)
@@ -2235,11 +2241,16 @@ prism54_process_bss_data(islpci_private
end = payload + len;
while (pos < end) {
if (pos + 2 + pos[1] > end) {
- printk(KERN_DEBUG "Parsing Beacon/ProbeResp failed "
- "for " MACSTR "\n", MAC2STR(addr));
+ printk(KERN_DEBUG "Parsing %s failed "
+ "for " MAC_FMT "\n", (oid == DOT11_OID_BEACON ? "Beacon" : "ProbeResp"), MAC_ARG(addr));
return;
}
- if (pos[0] == WLAN_EID_GENERIC && pos[1] >= 4 &&
+ /* Don't forget RSN/WPA2 ! */
+ if (pos[0] == MFIE_TYPE_RSN && pos[1] > 4) {
+ prism54_wpa_bss_ie_add(priv, addr, pos, pos[1] + 2);
+ return;
+ }
+ if (pos[0] == MFIE_TYPE_GENERIC && pos[1] >= 4 &&
memcmp(pos + 2, wpa_oid, 4) == 0) {
prism54_wpa_bss_ie_add(priv, addr, pos, pos[1] + 2);
return;
@@ -2264,39 +2275,81 @@ handle_request(islpci_private *priv, str
}
static int
+prism54_process_sta_trap(islpci_private *priv, enum oid_num_t oid,
+ struct obj_mlmeex* mlmeex)
+{
+ struct obj_mlme *mlme = (struct obj_mlme*)mlmeex;
+ int ret = 0;
+
+ switch (oid) {
+ case DOT11_OID_DEAUTHENTICATEEX:
+ send_formatted_event(priv, "DeAuthenticate request",
+ mlme, 0);
+ break;
+
+ case DOT11_OID_AUTHENTICATEEX:
+ if (prism54_mac_accept(&priv->acl, mlmeex->address) &&
+ (mlmeex->state == DOT11_STATE_AUTH)) {
+
+ mlmeex->state = DOT11_STATE_ASSOCING;
+ mlmeex->code = 0;
+ mlmeex->size = 0;
+ ret = mgt_set_request(priv, DOT11_OID_ASSOCIATEEX,
+ 0, mlmeex);
+ if (ret)
+ return ret;
+ }
+ if (mlmeex->code != 0)
+ send_formatted_event(priv, "Authenticate request",
+ mlme, 1);
+ break;
+
+ case DOT11_OID_DISASSOCIATEEX:
+ send_formatted_event(priv, "Disassociate request",
+ mlme, 0);
+ break;
+
+ case DOT11_OID_ASSOCIATEEX:
+ if (mlmeex->code)
+ send_formatted_event(priv, "Associate request",
+ mlme, 1);
+ break;
+
+ case DOT11_OID_REASSOCIATEEX:
+ if (mlmeex->code)
+ send_formatted_event(priv, "Reassociate request",
+ mlme, 1);
+ break;
+
+ default:
+ printk(KERN_INFO "%s: Unhandled OID %x, "
+ "please fill a bug-report!\n", priv->ndev->name, oid);
+ break;
+ }
+
+ return ret;
+}
+
+static int
prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
char *data)
{
struct obj_mlme *mlme = (struct obj_mlme *) data;
struct obj_mlmeex *mlmeex = (struct obj_mlmeex *) data;
- struct obj_mlmeex *confirm;
- u8 wpa_ie[MAX_WPA_IE_LEN];
- int wpa_ie_len;
- size_t len = 0; /* u16, better? */
- u8 *payload = NULL, *pos = NULL;
- int ret;
-
- /* I think all trapable objects are listed here.
- * Some oids have a EX version. The difference is that they are emitted
- * in DOT11_MLME_EXTENDED mode (set with DOT11_OID_MLMEAUTOLEVEL)
- * with more info.
- * The few events already defined by the wireless tools are not really
- * suited. We use the more flexible custom event facility.
- */
-
- if (oid >= DOT11_OID_BEACON) {
- len = mlmeex->size;
- payload = pos = mlmeex->data;
- }
+ int ret = 0;
/* I fear prism54_process_bss_data won't work with big endian data */
- if ((oid == DOT11_OID_BEACON) || (oid == DOT11_OID_PROBE))
- prism54_process_bss_data(priv, oid, mlmeex->address,
- payload, len);
mgt_le_to_cpu(isl_oid[oid].flags & OID_FLAG_TYPE, (void *) mlme);
switch (oid) {
+ case DOT11_OID_BEACON:
+ case DOT11_OID_PROBE:
+ if (priv->iw_mode != IW_MODE_MASTER
+ && mlmeex->state != DOT11_STATE_AUTHING)
+ prism54_process_bss_data(priv, oid, mlmeex->address,
+ mlmeex->data, mlmeex->size);
+ break;
case GEN_OID_LINKSTATE:
link_changed(priv->ndev, (u32) *data);
@@ -2329,163 +2382,12 @@ prism54_process_trap_helper(islpci_priva
send_formatted_event(priv, "ReAssociate request", mlme, 1);
break;
- case DOT11_OID_BEACON:
- send_formatted_event(priv,
- "Received a beacon from an unkown AP",
- mlme, 0);
- break;
-
- case DOT11_OID_PROBE:
- /* we received a probe from a client. */
- send_formatted_event(priv, "Received a probe from client", mlme,
- 0);
- break;
-
- /* Note : "mlme" is actually a "struct obj_mlmeex *" here, but this
- * is backward compatible layout-wise with "struct obj_mlme".
- */
-
- case DOT11_OID_DEAUTHENTICATEEX:
- send_formatted_event(priv, "DeAuthenticate request", mlme, 0);
- break;
-
- case DOT11_OID_AUTHENTICATEEX:
- handle_request(priv, mlme, oid);
- send_formatted_event(priv, "Authenticate request (ex)", mlme, 1);
-
- if (priv->iw_mode != IW_MODE_MASTER
- && mlmeex->state != DOT11_STATE_AUTHING)
- break;
-
- confirm = kmalloc(sizeof(struct obj_mlmeex) + 6, GFP_ATOMIC);
-
- 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]
- );
- confirm->id = -1; /* or mlmeex->id ? */
- confirm->state = 0; /* not used */
- confirm->code = 0;
- confirm->size = 6;
- confirm->data[0] = 0x00;
- confirm->data[1] = 0x00;
- confirm->data[2] = 0x02;
- confirm->data[3] = 0x00;
- confirm->data[4] = 0x00;
- confirm->data[5] = 0x00;
-
- ret = mgt_set_varlen(priv, DOT11_OID_ASSOCIATEEX, confirm, 6);
-
- kfree(confirm);
- if (ret)
- return ret;
- break;
-
- case DOT11_OID_DISASSOCIATEEX:
- send_formatted_event(priv, "Disassociate request (ex)", mlme, 0);
- break;
-
- case DOT11_OID_ASSOCIATEEX:
- handle_request(priv, mlme, oid);
- send_formatted_event(priv, "Associate request (ex)", mlme, 1);
-
- if (priv->iw_mode != IW_MODE_MASTER
- && mlmeex->state != DOT11_STATE_ASSOCING)
- break;
-
- confirm = kmalloc(sizeof(struct obj_mlmeex), GFP_ATOMIC);
-
- if (!confirm)
- break;
-
- memcpy(&confirm->address, mlmeex->address, ETH_ALEN);
-
- confirm->id = ((struct obj_mlmeex *)mlme)->id;
- confirm->state = 0; /* not used */
- confirm->code = 0;
-
- 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]
- );
- kfree(confirm);
- break;
- }
-
- 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;
-
- 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
- && mlmeex->state != DOT11_STATE_ASSOCING)
- break;
-
- confirm = kmalloc(sizeof(struct obj_mlmeex), GFP_ATOMIC);
-
- if (!confirm)
- break;
-
- memcpy(&confirm->address, mlmeex->address, ETH_ALEN);
-
- confirm->id = mlmeex->id;
- confirm->state = 0; /* not used */
- confirm->code = 0;
-
- 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]
- );
- kfree(confirm);
- break;
- }
-
- 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:
- return -EINVAL;
+ ret = prism54_process_sta_trap(priv, oid, mlmeex);
+ break;
}
- return 0;
+ return ret;
}
/*
@@ -2521,368 +2423,33 @@ prism54_set_mac_address(struct net_devic
return ret;
}
-/* Note: currently, use hostapd ioctl from the Host AP driver for WPA
- * support. This is to be replaced with Linux wireless extensions once they
- * get WPA support. */
-
-/* Note II: please leave all this together as it will be easier to remove later,
- * once wireless extensions add WPA support -mcgrof */
-
-/* PRISM54_HOSTAPD ioctl() cmd: */
-enum {
- PRISM2_SET_ENCRYPTION = 6,
- PRISM2_HOSTAPD_SET_GENERIC_ELEMENT = 12,
- PRISM2_HOSTAPD_MLME = 13,
- PRISM2_HOSTAPD_SCAN_REQ = 14,
-};
-
-#define PRISM54_SET_WPA SIOCIWFIRSTPRIV+12
-#define PRISM54_HOSTAPD SIOCIWFIRSTPRIV+25
-#define PRISM54_DROP_UNENCRYPTED SIOCIWFIRSTPRIV+26
-
-#define PRISM2_HOSTAPD_MAX_BUF_SIZE 1024
-#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)
- * used in ioctl() */
-#define HOSTAP_CRYPT_ALG_NAME_LEN 16
-
-struct prism2_hostapd_param {
- u32 cmd;
- u8 sta_addr[ETH_ALEN];
- union {
- struct {
- u8 alg[HOSTAP_CRYPT_ALG_NAME_LEN];
- u32 flags;
- u32 err;
- u8 idx;
- u8 seq[8]; /* sequence counter (set: RX, get: TX) */
- u16 key_len;
- u8 key[0];
- } crypt;
- struct {
- u8 len;
- u8 data[0];
- } generic_elem;
- struct {
-#define MLME_STA_DEAUTH 0
-#define MLME_STA_DISASSOC 1
- u16 cmd;
- u16 reason_code;
- } mlme;
- struct {
- u8 ssid_len;
- u8 ssid[32];
- } scan_req;
- } u;
-};
-
-
-static int
-prism2_ioctl_set_encryption(struct net_device *dev,
- struct prism2_hostapd_param *param,
- int param_len)
-{
- islpci_private *priv = netdev_priv(dev);
- int rvalue = 0, force = 0;
- int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0;
- union oid_res_t r;
-
- /* with the new API, it's impossible to get a NULL pointer.
- * New version of iwconfig set the IW_ENCODE_NOKEY flag
- * when no key is given, but older versions don't. */
-
- if (param->u.crypt.key_len > 0) {
- /* we have a key to set */
- int index = param->u.crypt.idx;
- int current_index;
- struct obj_key key = { DOT11_PRIV_TKIP, 0, "" };
-
- /* get the current key index */
- rvalue = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
- current_index = r.u;
- /* Verify that the key is not marked as invalid */
- if (!(param->u.crypt.flags & IW_ENCODE_NOKEY)) {
- key.length = param->u.crypt.key_len > sizeof (param->u.crypt.key) ?
- sizeof (param->u.crypt.key) : param->u.crypt.key_len;
- memcpy(key.key, param->u.crypt.key, key.length);
- if (key.length == 32)
- /* we want WPA-PSK */
- key.type = DOT11_PRIV_TKIP;
- if ((index < 0) || (index > 3))
- /* no index provided use the current one */
- index = current_index;
-
- /* now send the key to the card */
- rvalue |=
- mgt_set_request(priv, DOT11_OID_DEFKEYX, index,
- &key);
- }
- /*
- * 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
- */
- if ((index == current_index) && (key.length > 0))
- force = 1;
- } else {
- int index = (param->u.crypt.flags & IW_ENCODE_INDEX) - 1;
- if ((index >= 0) && (index <= 3)) {
- /* we want to set the key index */
- rvalue |=
- mgt_set_request(priv, DOT11_OID_DEFKEYID, 0,
- &index);
- } else {
- if (!param->u.crypt.flags & IW_ENCODE_MODE) {
- /* we cannot do anything. Complain. */
- return -EINVAL;
- }
- }
- }
- /* now read the flags */
- if (param->u.crypt.flags & IW_ENCODE_DISABLED) {
- /* Encoding disabled,
- * authen = DOT11_AUTH_OS;
- * invoke = 0;
- * exunencrypt = 0; */
- }
- if (param->u.crypt.flags & IW_ENCODE_OPEN)
- /* Encode but accept non-encoded packets. No auth */
- invoke = 1;
- if ((param->u.crypt.flags & IW_ENCODE_RESTRICTED) || force) {
- /* Refuse non-encoded packets. Auth */
- authen = DOT11_AUTH_BOTH;
- invoke = 1;
- exunencrypt = 1;
- }
- /* do the change if requested */
- if ((param->u.crypt.flags & IW_ENCODE_MODE) || force) {
- rvalue |=
- mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
- rvalue |=
- mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &invoke);
- rvalue |=
- mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0,
- &exunencrypt);
- }
- return rvalue;
-}
-
-static int
-prism2_ioctl_set_generic_element(struct net_device *ndev,
- struct prism2_hostapd_param *param,
- int param_len)
-{
- islpci_private *priv = netdev_priv(ndev);
- int max_len, len, alen, ret=0;
- struct obj_attachment *attach;
-
- len = param->u.generic_elem.len;
- max_len = param_len - PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN;
- if (max_len < 0 || max_len < len)
- return -EINVAL;
-
- alen = sizeof(*attach) + len;
- attach = kmalloc(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
-
- /* Note: endianness is covered by mgt_set_varlen */
-
- attach->type = (WLAN_FC_TYPE_MGMT << 2) |
- (WLAN_FC_STYPE_ASSOC_REQ << 4);
- attach->id = -1;
- attach->size = len;
- memcpy(attach->data, param->u.generic_elem.data, len);
-
- ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach, len);
-
- if (ret == 0) {
- attach->type = (WLAN_FC_TYPE_MGMT << 2) |
- (WLAN_FC_STYPE_REASSOC_REQ << 4);
-
- ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach, len);
-
- if (ret == 0)
- printk(KERN_DEBUG "%s: WPA IE Attachment was set\n",
- ndev->name);
- }
-
- kfree(attach);
- return ret;
-
-}
-
-static int
-prism2_ioctl_mlme(struct net_device *dev, struct prism2_hostapd_param *param)
-{
- return -EOPNOTSUPP;
-}
-
-static int
-prism2_ioctl_scan_req(struct net_device *ndev,
- struct prism2_hostapd_param *param)
-{
- islpci_private *priv = netdev_priv(ndev);
- int i, rvalue;
- struct obj_bsslist *bsslist;
- u32 noise = 0;
- char *extra = "";
- char *current_ev = "foo";
- union oid_res_t r;
-
- if (islpci_get_state(priv) < PRV_STATE_INIT) {
- /* device is not ready, fail gently */
- return 0;
- }
-
- /* first get the noise value. We will use it to report the link quality */
- rvalue = mgt_get_request(priv, DOT11_OID_NOISEFLOOR, 0, NULL, &r);
- noise = r.u;
-
- /* Ask the device for a list of known bss. We can report at most
- * IW_MAX_AP=64 to the range struct. 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 < min(IW_MAX_AP, (int) bsslist->nr); i++)
- current_ev = prism54_translate_bss(ndev, current_ev,
- extra + IW_SCAN_MAX_DATA,
- &(bsslist->bsslist[i]),
- noise);
- kfree(bsslist);
-
- return rvalue;
-}
-
-static int
-prism54_hostapd(struct net_device *ndev, struct iw_point *p)
-{
- struct prism2_hostapd_param *param;
- int ret = 0;
- u32 uwrq;
-
- printk(KERN_DEBUG "prism54_hostapd - len=%d\n", p->length);
- if (p->length < sizeof(struct prism2_hostapd_param) ||
- p->length > PRISM2_HOSTAPD_MAX_BUF_SIZE || !p->pointer)
- return -EINVAL;
-
- param = (struct prism2_hostapd_param *) kmalloc(p->length, GFP_KERNEL);
- if (param == NULL)
- return -ENOMEM;
-
- if (copy_from_user(param, p->pointer, p->length)) {
- kfree(param);
- return -EFAULT;
- }
-
- switch (param->cmd) {
- case PRISM2_SET_ENCRYPTION:
- printk(KERN_DEBUG "%s: Caught WPA supplicant set encryption request\n",
- ndev->name);
- ret = prism2_ioctl_set_encryption(ndev, param, p->length);
- break;
- case PRISM2_HOSTAPD_SET_GENERIC_ELEMENT:
- printk(KERN_DEBUG "%s: Caught WPA supplicant set WPA IE request\n",
- ndev->name);
- ret = prism2_ioctl_set_generic_element(ndev, param,
- p->length);
- break;
- case PRISM2_HOSTAPD_MLME:
- printk(KERN_DEBUG "%s: Caught WPA supplicant MLME request\n",
- ndev->name);
- ret = prism2_ioctl_mlme(ndev, param);
- break;
- case PRISM2_HOSTAPD_SCAN_REQ:
- printk(KERN_DEBUG "%s: Caught WPA supplicant scan request\n",
- ndev->name);
- ret = prism2_ioctl_scan_req(ndev, param);
- break;
- case PRISM54_SET_WPA:
- printk(KERN_DEBUG "%s: Caught WPA supplicant wpa init request\n",
- ndev->name);
- uwrq = 1;
- ret = prism54_set_wpa(ndev, NULL, &uwrq, NULL);
- break;
- case PRISM54_DROP_UNENCRYPTED:
- printk(KERN_DEBUG "%s: Caught WPA drop unencrypted request\n",
- ndev->name);
-#if 0
- uwrq = 0x01;
- mgt_set(priv, DOT11_OID_EXUNENCRYPTED, &uwrq);
- down_write(&priv->mib_sem);
- mgt_commit(priv);
- up_write(&priv->mib_sem);
-#endif
- /* Not necessary, as set_wpa does it, should we just do it here though? */
- ret = 0;
- break;
- default:
- printk(KERN_DEBUG "%s: Caught a WPA supplicant request that is not supported\n",
- ndev->name);
- ret = -EOPNOTSUPP;
- break;
- }
-
- if (ret == 0 && copy_to_user(p->pointer, param, p->length))
- ret = -EFAULT;
-
- kfree(param);
-
- return ret;
-}
-
static int
prism54_set_wpa(struct net_device *ndev, struct iw_request_info *info,
__u32 * uwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
- u32 mlme, authen, dot1x, filter, wep;
+ u32 mlme, dot1x;
if (islpci_get_state(priv) < PRV_STATE_INIT)
return 0;
- wep = 1; /* For privacy invoked */
- filter = 1; /* Filter out all unencrypted frames */
- dot1x = 0x01; /* To enable eap filter */
- mlme = DOT11_MLME_EXTENDED;
- authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
+ dot1x = 0; // disable global filtering
+ mlme = DOT11_MLME_AUTO;
down_write(&priv->mib_sem);
priv->wpa = *uwrq;
- switch (priv->wpa) {
- default:
- case 0: /* Clears/disables WPA and friends */
- wep = 0;
- filter = 0; /* Do not filter un-encrypted data */
- dot1x = 0;
- mlme = DOT11_MLME_AUTO;
- printk("%s: Disabling WPA\n", ndev->name);
- break;
- case 2:
- case 1: /* WPA */
- printk("%s: Enabling WPA\n", ndev->name);
- break;
+ if (priv->wpa) {
+ if (priv->iw_mode == IW_MODE_MASTER)
+ dot1x = 1;
+ mlme = DOT11_MLME_EXTENDED;
}
up_write(&priv->mib_sem);
- mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
- mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &wep);
- mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0, &filter);
mgt_set_request(priv, DOT11_OID_DOT1XENABLE, 0, &dot1x);
mgt_set_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, &mlme);
- return 0;
+ return prism54_set_auth_alg(priv, IW_ENCODE_OPEN);
}
static int
@@ -2890,7 +2457,9 @@ prism54_get_wpa(struct net_device *ndev,
__u32 * uwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
+ down_write(&priv->mib_sem);
*uwrq = priv->wpa;
+ up_write(&priv->mib_sem);
return 0;
}
@@ -3025,6 +2594,80 @@ prism54_set_spy(struct net_device *ndev,
return iw_handler_set_spy(ndev, info, uwrq, extra);
}
+static int
+prism54_send_mlme(struct net_device *ndev, struct iw_request_info *info,
+ struct iw_point *dwrq, char *extra)
+{
+ islpci_private *priv = netdev_priv(ndev);
+ struct iw_mlme *iwmlme;
+ struct obj_mlme mlme;
+ struct obj_sta *sta;
+ union oid_res_t r;
+ int ret = 0;
+
+ if (dwrq->length != sizeof(*iwmlme))
+ return -EINVAL;
+
+ iwmlme = (struct iw_mlme*)extra;
+
+ if (iwmlme->addr.sa_family != ARPHRD_ETHER)
+ return -EINVAL;
+
+ /* get STA/AP Id.
+ or the card will BROADCAST the packet! */
+
+ sta = (struct obj_sta*)kzalloc(sizeof(*sta), GFP_KERNEL);
+ if (!sta)
+ return -ENOMEM;
+
+ memcpy(sta->address, iwmlme->addr.sa_data, ETH_ALEN);
+ ret = mgt_get_request(priv, DOT11_OID_CLIENTFIND, 0, sta, &r);
+ kfree(sta);
+
+ if (ret) {
+ sta = r.ptr;
+ memcpy(mlme.address, iwmlme->addr.sa_data, ETH_ALEN);
+
+ if (sta->node >= 1)
+ mlme.id = sta->node;
+ else
+ mlme.id = -1;
+ } else
+ /* use broadcast id */
+ mlme.id = -1;
+
+ mlme.code = iwmlme->reason_code;
+
+ kfree(r.ptr);
+ switch (iwmlme->cmd) {
+ case IW_MLME_DEAUTH:
+ mlme.state = DOT11_STATE_NONE;
+ return mgt_set_request(priv, DOT11_OID_DEAUTHENTICATE,
+ 0, &mlme);
+ break;
+ case IW_MLME_DISASSOC:
+ mlme.state = DOT11_STATE_NONE;
+ return mgt_set_request(priv, DOT11_OID_DISASSOCIATE,
+ 0, &mlme);
+ break;
+#if 0
+ /* not in WEXT yet */
+ case IW_MLME_AUTH:
+ mlme.state = DOT11_STATE_AUTH;
+ return mgt_set_request(priv, DOT11_OID_AUTHENTICATE,
+ 0, &mlme);
+ break;
+ case IW_MLME_ASSOC:
+ mlme.state = DOT11_STATE_ASSOC;
+ return mgt_set_request(priv, DOT11_OID_ASSOCIATE,
+ 0, &mlme);
+ break;
+#endif
+ }
+
+ return -EOPNOTSUPP;
+}
+
static const iw_handler prism54_handler[] = {
(iw_handler) prism54_commit, /* SIOCSIWCOMMIT */
(iw_handler) prism54_get_name, /* SIOCGIWNAME */
@@ -3042,13 +2685,13 @@ static const iw_handler prism54_handler[
(iw_handler) NULL, /* SIOCGIWPRIV */
(iw_handler) NULL, /* SIOCSIWSTATS */
(iw_handler) NULL, /* SIOCGIWSTATS */
- prism54_set_spy, /* SIOCSIWSPY */
+ (iw_handler) prism54_set_spy, /* SIOCSIWSPY */
iw_handler_get_spy, /* SIOCGIWSPY */
iw_handler_set_thrspy, /* SIOCSIWTHRSPY */
iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
(iw_handler) prism54_set_wap, /* SIOCSIWAP */
(iw_handler) prism54_get_wap, /* SIOCGIWAP */
- (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) prism54_send_mlme, /* SIOCSIWMLME */
(iw_handler) NULL, /* SIOCGIWAPLIST depreciated */
(iw_handler) prism54_set_scan, /* SIOCSIWSCAN */
(iw_handler) prism54_get_scan, /* SIOCGIWSCAN */
@@ -3072,15 +2715,15 @@ static const iw_handler prism54_handler[
(iw_handler) prism54_get_encode, /* SIOCGIWENCODE */
(iw_handler) NULL, /* SIOCSIWPOWER */
(iw_handler) NULL, /* SIOCGIWPOWER */
- NULL, /* -- hole -- */
- NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
(iw_handler) prism54_set_genie, /* SIOCSIWGENIE */
(iw_handler) prism54_get_genie, /* SIOCGIWGENIE */
(iw_handler) prism54_set_auth, /* SIOCSIWAUTH */
(iw_handler) prism54_get_auth, /* SIOCGIWAUTH */
- (iw_handler) prism54_set_encodeext, /* SIOCSIWENCODEEXT */
- (iw_handler) prism54_get_encodeext, /* SIOCGIWENCODEEXT */
- NULL, /* SIOCSIWPMKSA */
+ (iw_handler) prism54_set_encodeext, /* SIOCSIWENCODEEXT */
+ (iw_handler) prism54_get_encodeext, /* SIOCGIWENCODEEXT */
+ (iw_handler) NULL /* SIOCSIWPMKSA */
};
/* The low order bit identify a SET (0) or a GET (1) ioctl. */
@@ -3259,14 +2902,5 @@ const struct iw_handler_def prism54_hand
int
prism54_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
{
- struct iwreq *wrq = (struct iwreq *) rq;
- int ret = -1;
- switch (cmd) {
- case PRISM54_HOSTAPD:
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- ret = prism54_hostapd(ndev, &wrq->u.data);
- return ret;
- }
return -EOPNOTSUPP;
}
diff --git a/drivers/net/wireless/prism54/isl_ioctl.h b/drivers/net/wireless/prism54/isl_ioctl.h
index e8183d3..8322133 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.h
+++ b/drivers/net/wireless/prism54/isl_ioctl.h
@@ -1,4 +1,5 @@
/*
+ *
* Copyright (C) 2002 Intersil Americas Inc.
* (C) 2003 Aurelien Alleaume <slts@free.fr>
* (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
@@ -21,12 +22,11 @@
#ifndef _ISL_IOCTL_H
#define _ISL_IOCTL_H
+#include <net/iw_handler.h> /* New driver API */
#include "islpci_mgt.h"
#include "islpci_dev.h"
-#include <net/iw_handler.h> /* New driver API */
-
-#define SUPPORTED_WIRELESS_EXT 19
+#define SUPPORTED_WIRELESS_EXT 21
void prism54_mib_init(islpci_private *);
diff --git a/drivers/net/wireless/prism54/isl_oid.h b/drivers/net/wireless/prism54/isl_oid.h
index b7534c2..88b24d6 100644
--- a/drivers/net/wireless/prism54/isl_oid.h
+++ b/drivers/net/wireless/prism54/isl_oid.h
@@ -2,6 +2,7 @@
* Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
* Copyright (C) 2004 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
* Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
+ * Copyright (C) 2006 Christian Lamparter <chunkeey@web.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,29 +27,67 @@
* with the device firmware
*/
+#define MAX_KEY_LEN 32
+
struct obj_ssid {
u8 length;
- char octets[33];
+ u8 octets[IW_ESSID_MAX_SIZE + 1];
} __attribute__ ((packed));
+enum dot11_priv_t {
+ DOT11_PRIV_WEP = 0,
+ DOT11_PRIV_TKIP = 1
+};
+
struct obj_key {
u8 type; /* dot11_priv_t */
u8 length;
- char key[32];
+ u8 key[MAX_KEY_LEN];
} __attribute__ ((packed));
+enum dot11_stakey_opt_t {
+ DOT11_STAKEY_OPTION_GROUPKEY = 0x0000,
+ DOT11_STAKEY_OPTION_DEFAULTKEY = 0x0001
+};
+
+enum dot11_keyop_t {
+ DOT11_KEYOP_SET_KEY = 0x0000,
+ DOT11_KEYOP_REMOVE_KEY = 0x0001
+};
+
+struct obj_stakey {
+ u8 address[ETH_ALEN];
+ u8 keyid;
+ u8 reserved; /* dot11_keyop_t */
+ u16 options; /* dot11_stakey_opt_t */
+ u8 type; /* dot11_priv_t */
+ u8 length;
+ u8 key[MAX_KEY_LEN];
+} __attribute__ ((packed));
+
+enum dot11_state_t {
+ DOT11_STATE_NONE = 0,
+ DOT11_STATE_AUTHING = 1,
+ DOT11_STATE_AUTH = 2,
+ DOT11_STATE_ASSOCING = 3,
+ DOT11_STATE_REASSOC = 4,
+ DOT11_STATE_ASSOC = 5,
+ DOT11_STATE_IBSS = 6,
+ DOT11_STATE_WDS = 7
+};
+
struct obj_mlme {
- u8 address[6];
+ u8 address[ETH_ALEN];
u16 id;
- u16 state;
- u16 code;
+ u16 state; /* dot11_state_t */
+ u16 code; /* WLAN_STATUS_ / WLAN_REASON_ */
} __attribute__ ((packed));
struct obj_mlmeex {
- u8 address[6];
+ u8 address[ETH_ALEN];
u16 id;
- u16 state;
- u16 code;
+ u16 state; /* dot11_state_t */
+ u16 code; /* WLAN_STATUS_ / WLAN_REASON_ */
u16 size;
u8 data[0];
} __attribute__ ((packed));
@@ -59,23 +98,23 @@ struct obj_buffer {
} __attribute__ ((packed));
struct obj_bss {
- u8 address[6];
+ u8 address[ETH_ALEN];
int:16; /* padding */
- char state;
- char reserved;
- short age;
+ u8 state; /* dot11_state_t */
+ u8 reserved;
+ u16 age;
- char quality;
- char rssi;
+ u8 quality;
+ u8 rssi;
struct obj_ssid ssid;
- short channel;
- char beacon_period;
- char dtim_period;
- short capinfo;
- short rates;
- short basic_rates;
+ u16 channel;
+ u8 beacon_period;
+ u8 dtim_period;
+ u16 capinfo; /* WLAN_CAPABILITY_ */
+ u16 rates;
+ u16 basic_rates;
int:16; /* padding */
} __attribute__ ((packed));
@@ -90,14 +129,33 @@ struct obj_frequencies {
} __attribute__ ((packed));
struct obj_attachment {
- char type;
- char reserved;
- short id;
- short size;
- char data[0];
+ u8 type; /* IEEE80211_STYPE_ */
+ u8 reserved;
+ u16 id;
+ u16 size;
+ u8 data[0];
} __attribute__((packed));
-/*
+struct obj_stasc {
+ u8 address[ETH_ALEN];
+ u8 keyid;
+ u8 tx_sc;
+ u8 sc[6];
+} __attribute__ ((packed));
+
+struct obj_sta {
+ u8 address[ETH_ALEN];
+ int:16;
+ u8 state; /* dot11_state_t */
+ u8 node; /* Station ID */
+ u16 age;
+ u8 reserved1;
+ u8 rssi;
+ u8 rate;
+ u8 reserved2;
+} __attribute__ ((packed));
+
+/*
* in case everything's ok, the inlined function below will be
* optimized away by the compiler...
*/
@@ -112,19 +170,12 @@ __bug_on_wrong_struct_sizes(void)
BUILD_BUG_ON(sizeof (struct obj_bss) != 60);
BUILD_BUG_ON(sizeof (struct obj_bsslist) != 4);
BUILD_BUG_ON(sizeof (struct obj_frequencies) != 2);
+ BUILD_BUG_ON(sizeof (struct obj_sta) != 16);
+ BUILD_BUG_ON(sizeof (struct obj_stasc) != 14);
+ BUILD_BUG_ON(sizeof (struct obj_stakey) != 44);
+ BUILD_BUG_ON(sizeof (struct obj_attachment) != 6);
}
-enum dot11_state_t {
- DOT11_STATE_NONE = 0,
- DOT11_STATE_AUTHING = 1,
- DOT11_STATE_AUTH = 2,
- DOT11_STATE_ASSOCING = 3,
-
- DOT11_STATE_ASSOC = 5,
- DOT11_STATE_IBSS = 6,
- DOT11_STATE_WDS = 7
-};
-
enum dot11_bsstype_t {
DOT11_BSSTYPE_NONE = 0,
DOT11_BSSTYPE_INFRA = 1,
@@ -145,11 +196,6 @@ enum dot11_mlme_t {
DOT11_MLME_EXTENDED = 2
};
-enum dot11_priv_t {
- DOT11_PRIV_WEP = 0,
- DOT11_PRIV_TKIP = 1
-};
-
/* Prism "Nitro" / Frameburst / "Packet Frame Grouping"
* Value is in microseconds. Represents the # microseconds
* the firmware will take to group frames before sending out then out
@@ -464,31 +510,32 @@ enum oid_num_t {
OID_NUM_LAST
};
-#define OID_FLAG_CACHED 0x80
-#define OID_FLAG_TYPE 0x7f
-
-#define OID_TYPE_U32 0x01
-#define OID_TYPE_SSID 0x02
-#define OID_TYPE_KEY 0x03
-#define OID_TYPE_BUFFER 0x04
-#define OID_TYPE_BSS 0x05
-#define OID_TYPE_BSSLIST 0x06
-#define OID_TYPE_FREQUENCIES 0x07
-#define OID_TYPE_MLME 0x08
-#define OID_TYPE_MLMEEX 0x09
-#define OID_TYPE_ADDR 0x0A
-#define OID_TYPE_RAW 0x0B
-#define OID_TYPE_ATTACH 0x0C
-
-/* OID_TYPE_MLMEEX is special because of a variable size field when sending.
- * Not yet implemented (not used in driver anyway).
- */
+enum oid_types_t {
+ OID_TYPE_U32 = 0x01,
+ OID_TYPE_SSID = 0x02,
+ OID_TYPE_KEY = 0x03,
+ OID_TYPE_BUFFER = 0x04,
+ OID_TYPE_BSS = 0x05,
+ OID_TYPE_BSSLIST = 0x06,
+ OID_TYPE_FREQUENCIES = 0x07,
+ OID_TYPE_MLME = 0x08,
+ OID_TYPE_MLMEEX = 0x09,
+ OID_TYPE_ADDR = 0x0A,
+ OID_TYPE_RAW = 0x0B,
+ OID_TYPE_ATTACH = 0x0C,
+ OID_TYPE_STASC = 0x0D,
+ OID_TYPE_STAKEY = 0x0E,
+ OID_TYPE_STAINFO = 0x0F,
+
+ OID_FLAG_CACHED = 0x80,
+ OID_FLAG_TYPE = 0x7f
+};
struct oid_t {
enum oid_num_t oid;
- short range; /* to define a range of oid */
- short size; /* max size of the associated data */
- char flags;
+ u16 range; /* to define a range of oid */
+ u16 size; /* max size of the associated data */
+ enum oid_types_t flags;
};
union oid_res_t {
@@ -496,8 +543,8 @@ union oid_res_t {
u32 u;
};
-#define IWMAX_BITRATES 20
-#define IWMAX_BSS 24
+#define IWMAX_BITRATES 20
+#define IWMAX_BSS 24
#define IWMAX_FREQ 30
#define PRIV_STR_SIZE 1024
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
index 1e0603c..e6d9b26 100644
--- a/drivers/net/wireless/prism54/islpci_dev.c
+++ b/drivers/net/wireless/prism54/islpci_dev.c
@@ -25,10 +25,10 @@
#include <linux/etherdevice.h>
#include <linux/delay.h>
#include <linux/if_arp.h>
+#include <linux/firmware.h>
#include <asm/io.h>
-#include "prismcompat.h"
#include "isl_38xx.h"
#include "isl_ioctl.h"
#include "islpci_dev.h"
@@ -86,7 +86,7 @@ isl_upload_firmware(islpci_private *priv
long fw_len;
const u32 *fw_ptr;
- rc = request_firmware(&fw_entry, priv->firmware, PRISM_FW_PDEV);
+ rc = request_firmware(&fw_entry, priv->firmware, &priv->pdev->dev);
if (rc) {
printk(KERN_ERR
"%s: request_firmware() failed for '%s'\n",
diff --git a/drivers/net/wireless/prism54/islpci_dev.h b/drivers/net/wireless/prism54/islpci_dev.h
index a9aa166..3d0bb8f 100644
--- a/drivers/net/wireless/prism54/islpci_dev.h
+++ b/drivers/net/wireless/prism54/islpci_dev.h
@@ -71,7 +71,6 @@ struct islpci_bss_wpa_ie {
u8 bssid[ETH_ALEN];
u8 wpa_ie[MAX_WPA_IE_LEN];
size_t wpa_ie_len;
-
};
typedef struct {
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
index 676d838..6da1f86 100644
--- a/drivers/net/wireless/prism54/islpci_eth.c
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -24,7 +24,6 @@
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
-#include "prismcompat.h"
#include "isl_38xx.h"
#include "islpci_eth.h"
#include "islpci_mgt.h"
@@ -482,8 +481,7 @@ islpci_eth_receive(islpci_private *priv)
void
islpci_do_reset_and_wake(void *data)
{
- islpci_private *priv = data;
-
+ islpci_private *priv = (islpci_private *) data;
islpci_reset(priv, 1);
priv->reset_task_pending = 0;
smp_wmb();
@@ -500,13 +498,12 @@ islpci_eth_tx_timeout(struct net_device
statistics->tx_errors++;
if (!priv->reset_task_pending) {
- printk(KERN_WARNING
- "%s: tx_timeout, scheduling reset", ndev->name);
+ printk(KERN_WARNING "%s: tx_timeout\n", ndev->name);
netif_stop_queue(ndev);
priv->reset_task_pending = 1;
schedule_work(&priv->reset_task);
} else {
printk(KERN_WARNING
- "%s: tx_timeout, waiting for reset", ndev->name);
+ "%s: tx_timeout, waiting for reset\n", ndev->name);
}
}
diff --git a/drivers/net/wireless/prism54/islpci_hotplug.c b/drivers/net/wireless/prism54/islpci_hotplug.c
index 58257b4..eba44e1 100644
--- a/drivers/net/wireless/prism54/islpci_hotplug.c
+++ b/drivers/net/wireless/prism54/islpci_hotplug.c
@@ -23,7 +23,6 @@
#include <linux/init.h> /* For __init, __exit */
#include <linux/dma-mapping.h>
-#include "prismcompat.h"
#include "islpci_dev.h"
#include "islpci_mgt.h" /* for pc_debug */
#include "isl_oid.h"
@@ -44,35 +43,15 @@ module_param(init_pcitm, int, 0);
* The latest list can be found at http://prism54.org/supported_cards.php */
static const struct pci_device_id prism54_id_tbl[] = {
/* Intersil PRISM Duette/Prism GT Wireless LAN adapter */
- {
- 0x1260, 0x3890,
- PCI_ANY_ID, PCI_ANY_ID,
- 0, 0, 0
- },
-
+ {PCI_DEVICE(0x1260, 0x3890)},
/* 3COM 3CRWE154G72 Wireless LAN adapter */
- {
- 0x10b7, 0x6001,
- PCI_ANY_ID, PCI_ANY_ID,
- 0, 0, 0
- },
-
+ {PCI_DEVICE(0x10b7, 0x6001)},
/* Intersil PRISM Indigo Wireless LAN adapter */
- {
- 0x1260, 0x3877,
- PCI_ANY_ID, PCI_ANY_ID,
- 0, 0, 0
- },
-
+ {PCI_DEVICE(0x1260, 0x3877)},
/* Intersil PRISM Javelin/Xbow Wireless LAN adapter */
- {
- 0x1260, 0x3886,
- PCI_ANY_ID, PCI_ANY_ID,
- 0, 0, 0
- },
-
+ {PCI_DEVICE(0x1260, 0x3886)},
/* End of list */
- {0,0,0,0,0,0,0}
+ { }
};
/* register the device with the Hotplug facilities of the kernel */
@@ -170,15 +149,15 @@ prism54_probe(struct pci_dev *pdev, cons
pci_set_master(pdev);
/* enable MWI */
- if (!pci_set_mwi(pdev))
- printk(KERN_INFO "%s: pci_set_mwi(pdev) succeeded\n", DRV_NAME);
+ if (pci_set_mwi(pdev))
+ printk(KERN_ERR "%s: pci_set_mwi failed\n", DRV_NAME);
/* setup the network device interface and its structure */
if (!(ndev = islpci_setup(pdev))) {
/* error configuring the driver as a network device */
printk(KERN_ERR "%s: could not configure network device\n",
DRV_NAME);
- goto do_pci_clear_mwi;
+ goto do_pci_release_regions;
}
priv = netdev_priv(ndev);
@@ -208,8 +187,6 @@ prism54_probe(struct pci_dev *pdev, cons
pci_set_drvdata(pdev, NULL);
free_netdev(ndev);
priv = NULL;
- do_pci_clear_mwi:
- pci_clear_mwi(pdev);
do_pci_release_regions:
pci_release_regions(pdev);
do_pci_disable_device:
@@ -257,8 +234,6 @@ prism54_remove(struct pci_dev *pdev)
free_netdev(ndev);
priv = NULL;
- pci_clear_mwi(pdev);
-
pci_release_regions(pdev);
pci_disable_device(pdev);
@@ -292,19 +267,15 @@ prism54_resume(struct pci_dev *pdev)
{
struct net_device *ndev = pci_get_drvdata(pdev);
islpci_private *priv = ndev ? netdev_priv(ndev) : NULL;
- int err;
-
BUG_ON(!priv);
- printk(KERN_NOTICE "%s: got resume request\n", ndev->name);
-
- err = pci_enable_device(pdev);
- if (err) {
- printk(KERN_ERR "%s: pci_enable_device failed on resume\n",
- ndev->name);
- return err;
+ if (pci_enable_device(pdev)) {
+ printk(KERN_ERR "%s: pci_enable_device() failed.\n", DRV_NAME);
+ return -ENODEV;
}
+ printk(KERN_NOTICE "%s: got resume request\n", ndev->name);
+
pci_restore_state(pdev);
/* alright let's go into the PREBOOT state */
diff --git a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c
index 036a875..8fd781d 100644
--- a/drivers/net/wireless/prism54/islpci_mgt.c
+++ b/drivers/net/wireless/prism54/islpci_mgt.c
@@ -25,7 +25,6 @@
#include <asm/system.h>
#include <linux/if_arp.h>
-#include "prismcompat.h"
#include "isl_38xx.h"
#include "islpci_mgt.h"
#include "isl_oid.h" /* additional types and defs for isl38xx fw */
diff --git a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c
index fbc52b6..24b5a49 100644
--- a/drivers/net/wireless/prism54/oid_mgt.c
+++ b/drivers/net/wireless/prism54/oid_mgt.c
@@ -16,7 +16,6 @@
*
*/
-#include "prismcompat.h"
#include "islpci_dev.h"
#include "islpci_mgt.h"
#include "isl_oid.h"
@@ -85,9 +84,9 @@ struct oid_t isl_oid[] = {
OID_U32_C(DOT11_OID_DEFKEYID, 0x12000003),
[DOT11_OID_DEFKEYX] = {0x12000004, 3, sizeof (struct obj_key),
OID_FLAG_CACHED | OID_TYPE_KEY}, /* DOT11_OID_DEFKEY1,...DOT11_OID_DEFKEY4 */
- OID_UNKNOWN(DOT11_OID_STAKEY, 0x12000008),
+ OID_STRUCT(DOT11_OID_STAKEY, 0x12000008, struct obj_stakey, OID_TYPE_STAKEY),
OID_U32(DOT11_OID_REKEYTHRESHOLD, 0x12000009),
- OID_UNKNOWN(DOT11_OID_STASC, 0x1200000a),
+ OID_STRUCT(DOT11_OID_STASC, 0x1200000a, struct obj_stasc, OID_TYPE_STASC),
OID_U32(DOT11_OID_PRIVTXREJECTED, 0x1a000000),
OID_U32(DOT11_OID_PRIVRXPLAIN, 0x1a000001),
@@ -122,9 +121,10 @@ struct oid_t isl_oid[] = {
OID_U32(DOT11_OID_BRIDGELOCAL, 0x15000000),
OID_U32(DOT11_OID_CLIENTS, 0x15000001),
OID_U32(DOT11_OID_CLIENTSASSOCIATED, 0x15000002),
- [DOT11_OID_CLIENTX] = {0x15000003, 2006, 0, 0}, /* DOT11_OID_CLIENTX,...DOT11_OID_CLIENT2007 */
+ [DOT11_OID_CLIENTX] = {0x15000003, 2006, sizeof(struct obj_sta),
+ OID_TYPE_STAINFO}, /* DOT11_OID_CLIENTX,...DOT11_OID_CLIENT2007 */
- OID_STRUCT(DOT11_OID_CLIENTFIND, 0x150007DB, u8[6], OID_TYPE_ADDR),
+ OID_STRUCT(DOT11_OID_CLIENTFIND, 0x150007DB, struct obj_sta, OID_TYPE_STAINFO),
OID_STRUCT(DOT11_OID_WDSLINKADD, 0x150007DC, u8[6], OID_TYPE_ADDR),
OID_STRUCT(DOT11_OID_WDSLINKREMOVE, 0x150007DD, u8[6], OID_TYPE_ADDR),
OID_STRUCT(DOT11_OID_EAPAUTHSTA, 0x150007DE, u8[6], OID_TYPE_ADDR),
@@ -201,8 +201,7 @@ struct oid_t isl_oid[] = {
OID_U32(DOT11_OID_STATIMEOUT, 0x19000000),
OID_U32_C(DOT11_OID_MLMEAUTOLEVEL, 0x19000001),
OID_U32(DOT11_OID_BSSTIMEOUT, 0x19000002),
- [DOT11_OID_ATTACHMENT] = {0x19000003, 0,
- sizeof(struct obj_attachment), OID_TYPE_ATTACH},
+ OID_STRUCT_C(DOT11_OID_ATTACHMENT, 0x19000003, sizeof(struct obj_attachment), OID_TYPE_ATTACH),
OID_STRUCT_C(DOT11_OID_PSMBUFFER, 0x19000004, struct obj_buffer,
OID_TYPE_BUFFER),
@@ -277,7 +276,7 @@ mgt_clean(islpci_private *priv)
}
void
-mgt_le_to_cpu(int type, void *data)
+mgt_le_to_cpu(enum oid_types_t type, void *data)
{
switch (type) {
case OID_TYPE_U32:
@@ -334,19 +333,31 @@ mgt_le_to_cpu(int type, void *data)
attach->id = le16_to_cpu(attach->id);
attach->size = le16_to_cpu(attach->size);
break;
- }
+ }
+ case OID_TYPE_STAKEY: {
+ struct obj_stakey *stakey = data;
+ stakey->options = le16_to_cpu(stakey->options);
+ break;
+ }
+ case OID_TYPE_STAINFO: {
+ struct obj_sta *sta = data;
+ sta->age = le16_to_cpu(sta->age);
+ break;
+ }
case OID_TYPE_SSID:
case OID_TYPE_KEY:
case OID_TYPE_ADDR:
case OID_TYPE_RAW:
+ case OID_TYPE_STASC:
break;
default:
BUG();
+ break;
}
}
static void
-mgt_cpu_to_le(int type, void *data)
+mgt_cpu_to_le(enum oid_types_t type, void *data)
{
switch (type) {
case OID_TYPE_U32:
@@ -403,14 +414,26 @@ mgt_cpu_to_le(int type, void *data)
attach->id = cpu_to_le16(attach->id);
attach->size = cpu_to_le16(attach->size);
break;
- }
+ }
+ case OID_TYPE_STAKEY: {
+ struct obj_stakey *stakey = data;
+ stakey->options = cpu_to_le16(stakey->options);
+ break;
+ }
+ case OID_TYPE_STAINFO: {
+ struct obj_sta *sta = data;
+ sta->age = cpu_to_le16(sta->age);
+ break;
+ }
case OID_TYPE_SSID:
case OID_TYPE_KEY:
case OID_TYPE_ADDR:
case OID_TYPE_RAW:
+ case OID_TYPE_STASC:
break;
default:
BUG();
+ break;
}
}
@@ -658,13 +681,16 @@ static enum oid_num_t commit_part1[] = {
static enum oid_num_t commit_part2[] = {
DOT11_OID_SSID,
+ /* problematic with WPA
DOT11_OID_PSMBUFFER,
+ */
DOT11_OID_AUTHENABLE,
DOT11_OID_PRIVACYINVOKED,
DOT11_OID_EXUNENCRYPTED,
DOT11_OID_DEFKEYX, /* MULTIPLE */
DOT11_OID_DEFKEYID,
DOT11_OID_DOT1XENABLE,
+ DOT11_OID_ATTACHMENT,
OID_INL_DOT11D_CONFORMANCE,
/* Do not initialize this - fw < 1.0.4.3 rejects it
OID_INL_OUTPUTPOWER,
diff --git a/drivers/net/wireless/prism54/oid_mgt.h b/drivers/net/wireless/prism54/oid_mgt.h
index 92c8a2d..10a5cc3 100644
--- a/drivers/net/wireless/prism54/oid_mgt.h
+++ b/drivers/net/wireless/prism54/oid_mgt.h
@@ -32,7 +32,7 @@ void mgt_clean(islpci_private *);
extern const int frequency_list_a[];
int channel_of_freq(int);
-void mgt_le_to_cpu(int, void *);
+void mgt_le_to_cpu(enum oid_types_t, void *);
int mgt_set_request(islpci_private *, enum oid_num_t, int, void *);
int mgt_set_varlen(islpci_private *, enum oid_num_t, void *, int);
diff --git a/drivers/net/wireless/prism54/prismcompat.h b/drivers/net/wireless/prism54/prismcompat.h
deleted file mode 100644
index aa1d174..0000000
--- a/drivers/net/wireless/prism54/prismcompat.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * (C) 2004 Margit Schubert-While <margitsw@t-online.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/*
- * Compatibility header file to aid support of different kernel versions
- */
-
-#ifdef PRISM54_COMPAT24
-#include "prismcompat24.h"
-#else /* PRISM54_COMPAT24 */
-
-#ifndef _PRISM_COMPAT_H
-#define _PRISM_COMPAT_H
-
-#include <linux/device.h>
-#include <linux/firmware.h>
-#include <linux/moduleparam.h>
-#include <linux/workqueue.h>
-#include <linux/compiler.h>
-
-#ifndef __iomem
-#define __iomem
-#endif
-
-#define PRISM_FW_PDEV &priv->pdev->dev
-
-#endif /* _PRISM_COMPAT_H */
-#endif /* PRISM54_COMPAT24 */
^ permalink raw reply related [flat|nested] 39+ messages in thread
* Re: [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
2006-11-26 10:47 ` chunkeey
@ 2006-12-06 1:44 ` John W. Linville
2006-12-06 12:05 ` chunkeey
0 siblings, 1 reply; 39+ messages in thread
From: John W. Linville @ 2006-12-06 1:44 UTC (permalink / raw)
To: chunkeey; +Cc: Dmitry Torokhov, netdev, Dmitry Torokhov, mcgrof
On Sun, Nov 26, 2006 at 11:47:49AM +0100, chunkeey@web.de wrote:
> On Sunday, 26. November 2006 06:27, you wrote:
> >
> > Sorry, still need the second "ifup" to bring the card up after plugging
> > it in. ping -f looks good however, I will try to stress it more and will
> > report if I see anything wrong.
>
> Well, some docs about the chips and firmware would be very handy...
> has anyone access to conexant's library?
FYI...after latest round of merges, that patch that I've been carrying
in the pending branch of wireless-2.6 no longer applies.
John
--
John W. Linville
linville@tuxdriver.com
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
2006-12-06 1:44 ` John W. Linville
@ 2006-12-06 12:05 ` chunkeey
2006-12-06 14:11 ` Dmitry Torokhov
0 siblings, 1 reply; 39+ messages in thread
From: chunkeey @ 2006-12-06 12:05 UTC (permalink / raw)
To: John W. Linville; +Cc: Dmitry Torokhov, Dmitry Torokhov, netdev
On Wednesday, 6. December 2006 02:44, you wrote:
> FYI...after latest round of merges, that patch that I've been carrying
> in the pending branch of wireless-2.6 no longer applies.
>
> John
Ok, I'm waiting for Dmitry' feedback... (hello, where're you ;) ?)
Christian
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH wireless-2.6-git] prism54: WPA/RSN support for fullmac cards
2006-12-06 12:05 ` chunkeey
@ 2006-12-06 14:11 ` Dmitry Torokhov
0 siblings, 0 replies; 39+ messages in thread
From: Dmitry Torokhov @ 2006-12-06 14:11 UTC (permalink / raw)
To: chunkeey@web.de; +Cc: John W. Linville, netdev
On 12/6/06, chunkeey@web.de <chunkeey@web.de> wrote:
> On Wednesday, 6. December 2006 02:44, you wrote:
> > FYI...after latest round of merges, that patch that I've been carrying
> > in the pending branch of wireless-2.6 no longer applies.
> >
> > John
>
> Ok, I'm waiting for Dmitry' feedback... (hello, where're you ;) ?)
>
Sorry, busy time... I still have to do "ifup eth1" manually after
inserting the card to get it going.
--
Dmitry
^ permalink raw reply [flat|nested] 39+ messages in thread
end of thread, other threads:[~2006-12-06 14:11 UTC | newest]
Thread overview: 39+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-10-03 12:57 [PATCH] prism54: wpa support for fullmac cards chunkeey
2006-10-04 10:38 ` Jiri Benc
2006-10-04 11:40 ` Dan Williams
2006-10-04 14:12 ` chunkeey
2006-10-04 21:43 ` Jouni Malinen
2006-10-05 17:17 ` chunkeey
2006-10-17 21:32 ` John W. Linville
2006-10-29 12:35 ` [PATCH wireless-2.6-git] prism54: WPA/RSN " chunkeey
2006-10-30 8:50 ` Johannes Berg
2006-10-30 20:17 ` Luis R. Rodriguez
2006-10-31 16:05 ` Dan Williams
2006-10-31 17:53 ` chunkeey
2006-11-03 14:49 ` Dan Williams
2006-11-03 16:06 ` Luis R. Rodriguez
2006-11-03 18:12 ` chunkeey
2006-11-03 18:41 ` Luis R. Rodriguez
2006-11-08 0:39 ` John W. Linville
2006-11-09 17:38 ` chunkeey
2006-11-09 23:16 ` Luis R. Rodriguez
2006-11-09 23:16 ` Luis R. Rodriguez
2006-11-10 14:42 ` Dan Williams
2006-11-17 5:42 ` Dmitry Torokhov
2006-11-17 19:43 ` chunkeey
2006-11-17 20:16 ` Dmitry Torokhov
2006-11-17 20:53 ` chunkeey
2006-11-17 21:02 ` Dmitry Torokhov
2006-11-17 21:09 ` Dmitry Torokhov
2006-11-17 21:35 ` chunkeey
2006-11-18 4:27 ` Dmitry Torokhov
2006-11-18 10:18 ` chunkeey
2006-11-22 7:01 ` Dmitry Torokhov
2006-11-24 15:55 ` chunkeey
[not found] ` <200611250039.03597.dtor@insightbb.com>
2006-11-25 16:50 ` chunkeey
2006-11-26 5:27 ` Dmitry Torokhov
2006-11-26 10:47 ` chunkeey
2006-12-06 1:44 ` John W. Linville
2006-12-06 12:05 ` chunkeey
2006-12-06 14:11 ` Dmitry Torokhov
2006-10-30 20:33 ` Dan Williams
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).